mirror of
https://github.com/ipmitool/ipmitool.git
synced 2025-07-01 10:13:35 +00:00
Compare commits
296 Commits
IPMITOOL_S
...
IPMITOOL_1
Author | SHA1 | Date | |
---|---|---|---|
ca9d7f702b | |||
d4a64e17f2 | |||
e855ba03df | |||
68cdacb211 | |||
85643e52a2 | |||
776080c88a | |||
f0cd89fea6 | |||
d6e85b8427 | |||
ed8a467f6d | |||
715add8fef | |||
da9252ceba | |||
ae1fe95cb1 | |||
f42f7c701c | |||
29f43931e4 | |||
2ea87e639b | |||
8ec87a396e | |||
cd7e75a9d5 | |||
738cf02694 | |||
f7519e00eb | |||
c546582e92 | |||
22c7f92135 | |||
f449928806 | |||
8a0559a651 | |||
6cb97e4327 | |||
a15d6a31ac | |||
77275ab616 | |||
32c94e3eae | |||
36e388648d | |||
aac4cc9e05 | |||
c552839583 | |||
9dd625a215 | |||
f50160a9e4 | |||
67a60f1c9d | |||
7eeae98fb4 | |||
ae92538cbb | |||
558f279597 | |||
4e9fb18ef6 | |||
dc7c60b7a8 | |||
38d0926d9f | |||
661a80433e | |||
a4c5e7bda0 | |||
cf40042856 | |||
92876549ab | |||
141721d220 | |||
1e0164c253 | |||
ecb214d423 | |||
1196369aaf | |||
bfe06ebd98 | |||
58e4e355f8 | |||
9d762b82a0 | |||
9ad01e6eed | |||
53c97bc5b4 | |||
6ab2eb972e | |||
e25e0b8e71 | |||
cfd7f610cb | |||
f9d19aa0c5 | |||
6a90734a67 | |||
2440c09d50 | |||
1f597a78e2 | |||
f4dd419fe6 | |||
b3472220af | |||
54d6016a31 | |||
864ac5ad26 | |||
17d68a4289 | |||
907d8b30f5 | |||
c2d9746775 | |||
51a92c0917 | |||
07f4139e70 | |||
6514de2b13 | |||
89f6d591e0 | |||
f9f0599908 | |||
c792f6e7e1 | |||
bce51c05f8 | |||
e0912fc6b7 | |||
2c117c95ea | |||
e7140ed0c8 | |||
6049aa0fe4 | |||
96876bb061 | |||
4d2f9ebdc2 | |||
54dfc91b2b | |||
86d54446e9 | |||
a7bcb2422e | |||
4067bafa57 | |||
624392f798 | |||
ac2cc29ac0 | |||
87540ecf2a | |||
6d77f698f2 | |||
083e6afc46 | |||
384f9219ba | |||
fef402714f | |||
312b564091 | |||
a85bd201df | |||
e633524d34 | |||
a892bb499a | |||
836149f966 | |||
694f92918f | |||
1fe48e8a36 | |||
380f330e15 | |||
fe38fb4e7b | |||
ffd03bc964 | |||
f9e30a894c | |||
f733bcf2f1 | |||
51e906b7c6 | |||
70cc60d8a4 | |||
c2c1204cb1 | |||
f87420b587 | |||
33cad9b907 | |||
b42902f880 | |||
8e77031a97 | |||
b7962d85dc | |||
36fefdabc3 | |||
0ad17ece4a | |||
990a9a4b6b | |||
df7d0e6ee6 | |||
0f3c980b49 | |||
8cfb4c0897 | |||
650f12ab23 | |||
fb0cc0187c | |||
723b7c0614 | |||
bac5e21634 | |||
2ef302401e | |||
cd174d8e73 | |||
718232945c | |||
fa3bb0960b | |||
b8a2890ace | |||
5a7385f780 | |||
9708c8326f | |||
b1cf8c6a2b | |||
3af858eecf | |||
f04b6d858f | |||
12c19f88ca | |||
4385f3c403 | |||
f598c42e2e | |||
a567ac9426 | |||
2d0c486541 | |||
1a4399a9eb | |||
58c0fa890b | |||
06147e6a37 | |||
d559b1fa2d | |||
bd30ca98db | |||
e5a6d23f9c | |||
81aa0855f8 | |||
281777996b | |||
57c49ef9b8 | |||
adb40e53a1 | |||
db3da49158 | |||
6f9b34313e | |||
081baa7e24 | |||
bbaf882dd1 | |||
9e4ad72524 | |||
ea0e9ca5fd | |||
ace510828f | |||
6cc2c67671 | |||
d5d36e1941 | |||
b65ec95257 | |||
6b8d9243c2 | |||
5c2cd09f6a | |||
e34c7eeb5c | |||
eb8653f02a | |||
24a0b44a98 | |||
d69b8e8b7f | |||
8b68086fdb | |||
35c6bb4a9d | |||
928c500484 | |||
2da00b9a47 | |||
04802db0e0 | |||
85d612fa35 | |||
1340786bda | |||
30eec7d0ac | |||
5298b1ca71 | |||
a292d94239 | |||
26557547b4 | |||
2c2437239d | |||
7b3fac2071 | |||
763abe4889 | |||
2a574a3e8b | |||
f108b55d13 | |||
13659fb466 | |||
412798482c | |||
90448837ec | |||
fecfc09c8b | |||
820d9e6bb3 | |||
251de396a1 | |||
774c74a64c | |||
c7c5b2de37 | |||
762f6fff1c | |||
4ea12d4308 | |||
ce01d13e98 | |||
1c4f38bba8 | |||
b2c96c3a1f | |||
4c99a6f676 | |||
78049bf3b7 | |||
6052a2b57a | |||
392454c646 | |||
805835ca69 | |||
c86c21e734 | |||
897b3c5a46 | |||
4e93bf01ed | |||
9573ee3eed | |||
ef4e6f3dad | |||
3d30271e73 | |||
c39a8026da | |||
20a4a2f950 | |||
55ac08dc49 | |||
3fa867b222 | |||
8169fc6b3f | |||
505ec7615d | |||
116c7a7cf9 | |||
5c1661707c | |||
c105728a9a | |||
08e8e99fe2 | |||
596ef14553 | |||
0d3daba614 | |||
b42a8d7d6f | |||
75ae0675c2 | |||
a427845e41 | |||
d2364e50b2 | |||
e05098f802 | |||
d7e971d92f | |||
4e59621e64 | |||
3da7fea17f | |||
9c476f36aa | |||
c575d4b028 | |||
775f349d04 | |||
69c50e3d73 | |||
e9c27522c0 | |||
14042e4021 | |||
47e42d3f32 | |||
344cd68cc1 | |||
8974794475 | |||
3a96ee3272 | |||
1fbd130b9b | |||
d2bee0687a | |||
34474dcb2a | |||
e7f78a54f9 | |||
2c87bfc701 | |||
d4b64f4277 | |||
9caeb52ec1 | |||
b27e296399 | |||
f29c7e699c | |||
04561e2433 | |||
6d1f8521e6 | |||
90e2c17543 | |||
1df7ca9588 | |||
6dae08746d | |||
413078f80b | |||
e2cd941c34 | |||
ca85cb4688 | |||
e067d97a41 | |||
ac3e23b9b9 | |||
a60b6acce1 | |||
daf5180838 | |||
3979342536 | |||
a12c0c31bb | |||
7094b4f838 | |||
f0b24c9a0e | |||
674eb706a3 | |||
fe4f77cfdd | |||
cd5ee61d23 | |||
f7dc0a57de | |||
c6db0382e5 | |||
761ce85d28 | |||
3d29ed01a5 | |||
bc17282c3a | |||
247ad8f661 | |||
5679de9984 | |||
15ed988689 | |||
34ddf53870 | |||
42e73b39de | |||
aca415c287 | |||
c4699aba9c | |||
be2c0c4b03 | |||
0d72cd27cc | |||
e4ba0c3de3 | |||
96bd14b905 | |||
8a2a11c520 | |||
9164d3b69e | |||
80a9f3acb2 | |||
94f272e8e2 | |||
682caca7ea | |||
d6274af150 | |||
1d7e045d47 | |||
8dd12afdad | |||
174b13e835 | |||
ff89a0e2f2 | |||
9dbab242bd | |||
658b502e64 | |||
b8d8587b2a | |||
445025f2f4 | |||
55ee755de8 | |||
e9281ea912 | |||
58ef4f8af6 | |||
2e5d0c2921 | |||
79421577cc | |||
651466fc41 | |||
072986b669 |
@ -1,3 +1,41 @@
|
||||
version 1.8.3
|
||||
* Add support for 'sel readraw' and 'sel writeraw' commands.
|
||||
* Add support for entering NetFn as a string for RAW commands.
|
||||
* Add support for appending distro tag to integrated RPM builds.
|
||||
* Fix LAN parameter printing to handle Invalid Data Field response
|
||||
without errors.
|
||||
* Add 5ms delay to IPMIv2 SOL retry packets
|
||||
* IPMIv2 interface will now correctly set session privilege level
|
||||
to requested level after session is opened.
|
||||
|
||||
version 1.8.2 (released May 18 2005)
|
||||
* Fix FRU reading for large (>255 bytes) areas.
|
||||
* Overhaul to ipmievd to support SEL polling in addition to OpenIPMI.
|
||||
* Fix LAN parameter segfault when no Ciphers supported by BMC.
|
||||
* Fix IPMIv2 support on Intel v2 BMCs (use -o intelplus).
|
||||
* Separate option parsing code from main ipmitool source file.
|
||||
* Add raw I2C support with IPMI Master Read-Write command.
|
||||
* Add support for new 'sdr elist' extended output format.
|
||||
* Add support for listing sensors by type with 'sdr type' command.
|
||||
* Add support for new 'sel elist' extended output format that
|
||||
cross-references events with sensors.
|
||||
* Add support for sending dynamically generated platform events
|
||||
based on existing sensor information.
|
||||
* New '-S' argument to read local SDR cache created with 'sdr dump'.
|
||||
* Updated manpage for ipmitool and ipmievd.
|
||||
|
||||
version 1.8.1
|
||||
* ipmievd installs in /usr/sbin
|
||||
|
||||
version 1.8.0
|
||||
* Fix IPMIv2.0 issues
|
||||
* Fix chassis boot parameter support
|
||||
* Add support for linear sensors
|
||||
|
||||
version 1.7.1
|
||||
* Update bmc plugin to work with new Solaris bmc driver (new ioctl
|
||||
for interface detection and new STREAMS message-based interface)
|
||||
|
||||
version 1.7.0
|
||||
* Propogate errors correctly so exit status will be useful
|
||||
* More consistent display of errors including completion code text
|
||||
|
@ -3,7 +3,7 @@ dnl autoconf for ipmitool
|
||||
dnl
|
||||
AC_INIT([src/ipmitool.c])
|
||||
AC_CANONICAL_SYSTEM
|
||||
AM_INIT_AUTOMAKE([ipmitool], [1.7.0])
|
||||
AM_INIT_AUTOMAKE([ipmitool], [1.8.5])
|
||||
AM_CONFIG_HEADER(config.h)
|
||||
AC_CONFIG_SRCDIR([src/ipmitool.c])
|
||||
AC_PREREQ(2.50)
|
||||
@ -18,7 +18,7 @@ AC_CHECK_PROG([RPMBUILD], [rpmbuild], [rpmbuild], [rpm])
|
||||
AC_CHECK_PROG([SED], [sed], [sed])
|
||||
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS([stdlib.h string.h sys/ioctl.h sys/stat.h unistd.h])
|
||||
AC_CHECK_HEADERS([stdlib.h string.h sys/ioctl.h sys/stat.h unistd.h paths.h termios.h])
|
||||
AC_CHECK_HEADERS([arpa/inet.h fcntl.h netdb.h netinet/in.h sys/socket.h])
|
||||
AC_CHECK_HEADERS([sys/byteorder.h byteswap.h])
|
||||
|
||||
@ -51,6 +51,8 @@ if test "x$exec_prefix" = "xNONE"; then
|
||||
exec_prefix="$prefix"
|
||||
fi
|
||||
|
||||
enable_all_options=yes
|
||||
|
||||
dnl set some things so we build with GNU tools on Solaris
|
||||
case "$host_os" in
|
||||
solaris*)
|
||||
@ -58,11 +60,35 @@ solaris*)
|
||||
STRIP=gstrip
|
||||
LD=gld
|
||||
AR=gar
|
||||
# openssl libs are in /usr/sfw/lib on solaris 10
|
||||
LIBS="$LIBS -R/usr/sfw/lib"
|
||||
# disable the linux-specific interfaces
|
||||
# and bmc on SPARC (there is no bmc driver for SPARC)
|
||||
if [[ `mach -p` = sparc ]]; then
|
||||
enable_intf_bmc=no
|
||||
else
|
||||
enable_intf_bmc=yes
|
||||
fi
|
||||
enable_intf_imb=no
|
||||
enable_intf_open=no
|
||||
enable_ipmievd=no
|
||||
enable_intf_lipmi=no
|
||||
enable_ipmishell=no
|
||||
enable_all_options=no
|
||||
;;
|
||||
*cygwin*)
|
||||
# disable the linux and solaris-specific interfaces
|
||||
enable_intf_imb=no
|
||||
enable_intf_open=no
|
||||
enable_intf_lipmi=no
|
||||
enable_intf_bmc=no
|
||||
enable_ipmishell=no
|
||||
;;
|
||||
*darwin*)
|
||||
# disable the linux and solaris-specific interfaces
|
||||
enable_intf_imb=no
|
||||
enable_intf_open=no
|
||||
enable_intf_lipmi=no
|
||||
enable_intf_bmc=no
|
||||
enable_ipmishell=no
|
||||
;;
|
||||
esac
|
||||
@ -72,6 +98,15 @@ AC_SUBST(OS, $host_os)
|
||||
AC_SUBST(PSTAMP, $host)
|
||||
AC_SUBST(BASEDIR, $prefix)
|
||||
|
||||
dnl allow solaris builds to include all options
|
||||
AC_ARG_ENABLE([solaris-opt],
|
||||
[AC_HELP_STRING([--enable-solaris-opt],
|
||||
[enable all options for Solaris [default=no]])],
|
||||
[], [enable_solaris_opt=no])
|
||||
if test "x$enable_all_options" = "xyes" || test "x$enable_solaris_opt" = "xyes"; then
|
||||
AC_DEFINE(ENABLE_ALL_OPTIONS, [1], [Define to 1 to enable all command line options.])
|
||||
fi
|
||||
|
||||
dnl check for OpenSSL functionality
|
||||
AC_ARG_ENABLE([internal-md5],
|
||||
[AC_HELP_STRING([--enable-internal-md5],
|
||||
@ -159,10 +194,16 @@ AC_CHECK_HEADER([linux/ipmi.h],
|
||||
[Define to 1 if you have the <linux/ipmi.h> header file.])],
|
||||
[echo "** Unable to find OpenIPMI header files. Using internal version."])
|
||||
|
||||
dnl set RPM distro tag for use in RPM name
|
||||
AC_ARG_WITH([rpm-distro],
|
||||
[AC_HELP_STRING([--with-rpm-distro=DISTRO],
|
||||
[set Linux distribution tag for use in RPM version string])],
|
||||
[AC_SUBST(DISTRO, $with_rpm_distro)])
|
||||
|
||||
dnl enable Linux OpenIPMI interface
|
||||
AC_ARG_ENABLE([intf-open],
|
||||
[AC_HELP_STRING([--enable-intf-open],
|
||||
[enable Linux OpenIPMI interface [default=yes]])],
|
||||
[enable Linux OpenIPMI interface [default=auto]])],
|
||||
[], [enable_intf_open=yes])
|
||||
if test "x$enable_intf_open" = "xstatic" || test "x$enable_intf_open" = "xplugin"; then
|
||||
enable_intf_open=yes
|
||||
@ -177,7 +218,7 @@ fi
|
||||
dnl enable Intel IMB interface
|
||||
AC_ARG_ENABLE([intf-imb],
|
||||
[AC_HELP_STRING([--enable-intf-imb],
|
||||
[enable Intel IMB driver interface [default=yes]])],
|
||||
[enable Intel IMB driver interface [default=auto]])],
|
||||
[], [enable_intf_imb=yes])
|
||||
if test "x$enable_intf_imb" = "xstatic" || test "x$enable_intf_imb" = "xplugin"; then
|
||||
enable_intf_imb=yes
|
||||
@ -212,7 +253,7 @@ fi
|
||||
dnl enable Solaris BMC interface
|
||||
AC_ARG_ENABLE([intf-bmc],
|
||||
[AC_HELP_STRING([--enable-intf-bmc],
|
||||
[enable Solaris 10 x86 IPMI interface [default=no]])],,
|
||||
[enable Solaris 10 x86 IPMI interface [default=auto]])],,
|
||||
[enable_intf_bmc=no])
|
||||
if test "x$enable_intf_bmc" = "xstatic" || test "x$enable_intf_bmc" = "xplugin"; then
|
||||
enable_intf_bmc=yes
|
||||
@ -232,29 +273,20 @@ 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([readline], [readline], [have_readline=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.])
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl enable IPMI Event Daemon
|
||||
AC_ARG_ENABLE([ipmievd],
|
||||
[AC_HELP_STRING([--enable-ipmievd],
|
||||
[enable IPMI Event daemon [default=yes]])],
|
||||
[], [enable_ipmievd=yes])
|
||||
AM_CONDITIONAL(IPMIEVD, [test "x$enable_ipmievd" = "xyes"])
|
||||
if test "x$enable_ipmievd" = "xyes"; then
|
||||
AC_SUBST(IPMIEVD_BIN, [ipmievd])
|
||||
fi
|
||||
|
||||
dnl Enable -Wall -Werror
|
||||
AC_ARG_ENABLE([buildcheck],
|
||||
[AC_HELP_STRING([--enable-buildcheck],
|
||||
[enable -Wall -Werror for build testing [default=no]])],
|
||||
[if test "x$enable_buildcheck" != "xno"; then
|
||||
CFLAGS="$CFLAGS -Wall -Werror"
|
||||
CFLAGS="$CFLAGS -Wall -Werror -Wpointer-arith -Wstrict-prototypes"
|
||||
fi], [])
|
||||
|
||||
AC_SUBST(CFLAGS)
|
||||
@ -266,6 +298,7 @@ AC_CONFIG_FILES([Makefile
|
||||
control/Makefile
|
||||
control/pkginfo
|
||||
control/prototype
|
||||
control/rpmmacros
|
||||
control/ipmitool.spec
|
||||
lib/Makefile
|
||||
include/Makefile
|
||||
@ -293,6 +326,6 @@ AC_MSG_RESULT([ bmc : $enable_intf_bmc])
|
||||
AC_MSG_RESULT([ lipmi : $enable_intf_lipmi])
|
||||
AC_MSG_RESULT([])
|
||||
AC_MSG_RESULT([Extra tools])
|
||||
AC_MSG_RESULT([ ipmievd : $enable_ipmievd])
|
||||
AC_MSG_RESULT([ ipmievd : yes])
|
||||
AC_MSG_RESULT([])
|
||||
|
||||
|
@ -34,7 +34,8 @@
|
||||
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
||||
dist_pkgdata_DATA = bmclanconf README \
|
||||
ipmi.init.basic ipmi.init.redhat \
|
||||
dist_pkgdata_DATA = README
|
||||
|
||||
dist_pkgdata_SCRIPTS = bmclanconf ipmi.init.basic ipmi.init.redhat \
|
||||
collect_data.sh create_rrds.sh create_webpage_compact.sh create_webpage.sh
|
||||
|
||||
|
@ -48,6 +48,12 @@ start() {
|
||||
# this failure.
|
||||
grep -q ipmidev /proc/devices || RETVAL=1
|
||||
|
||||
# remove old device file always
|
||||
# in case ipmi gets assigned new dynamic major number from kernel
|
||||
if [ -c /dev/ipmi0 ]; then
|
||||
rm -f /dev/ipmi0
|
||||
fi
|
||||
|
||||
# Check if the device file exists and create if not.
|
||||
if [ ! -c /dev/ipmi0 ] && [ $RETVAL -eq 0 ]
|
||||
then
|
||||
|
@ -34,8 +34,8 @@
|
||||
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
||||
EXTRA_DIST = pkginfo.in prototype.in ipmitool.spec.in \
|
||||
rpmrc rpmmacros
|
||||
EXTRA_DIST = pkginfo.in prototype.in \
|
||||
ipmitool.spec.in rpmmacros.in rpmrc
|
||||
|
||||
dist-hook: pkginfo prototype
|
||||
dist-hook: pkginfo prototype rpmmacros
|
||||
|
||||
|
@ -32,8 +32,10 @@ fi
|
||||
|
||||
%build
|
||||
./configure --with-kerneldir \
|
||||
--with-rpm-distro=@DISTRO@ \
|
||||
--prefix=%{_prefix} \
|
||||
--bindir=%{_bindir} \
|
||||
--sbindir=%{_sbindir} \
|
||||
--datadir=%{_datadir} \
|
||||
--includedir=%{_includedir} \
|
||||
--libdir=%{_libdir} \
|
||||
@ -53,11 +55,65 @@ 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/*
|
||||
|
||||
%changelog
|
||||
* Sat Jan 14, 2006 <duncan@iceblink.org> 1.8.5-1
|
||||
- Raise privilege level after creating IPMIv2 session
|
||||
- Add support for settable SOL escape character with -e option
|
||||
- Add support for Kg BMC key for IPMIv2 authentication with -k option
|
||||
- Add support for Tyan IPMIv1.5 SOL with tsol command
|
||||
- Add support for PICMG devices
|
||||
- Add support for OEM SEL event parsing
|
||||
- Add support for command bridging over lan and lanplus interfaces
|
||||
- New 'chassis selftest' command
|
||||
- Many bufxies and patches from contributors
|
||||
|
||||
* Wed May 18 2005 <duncan@iceblink.org> 1.8.2-1
|
||||
- Fix FRU reading for large (>255 bytes) areas.
|
||||
- Overhaul to ipmievd to support SEL polling in addition to OpenIPMI.
|
||||
- Fix LAN parameter segfault when no Ciphers supported by BMC.
|
||||
- Fix IPMIv2 support on Intel v2 BMCs (use -o intelplus).
|
||||
- Separate option parsing code from main ipmitool source file.
|
||||
- Add raw I2C support with IPMI Master Read-Write command.
|
||||
- Add support for new 'sdr elist' extended output format.
|
||||
- Add support for listing sensors by type with 'sdr type' command.
|
||||
- Add support for new 'sel elist' extended output format that
|
||||
cross-references events with sensors.
|
||||
- Add support for sending dynamically generated platform events
|
||||
based on existing sensor information.
|
||||
- New '-S' argument to read local SDR cache created with 'sdr dump'.
|
||||
- Updated manpage for ipmitool and ipmievd.
|
||||
|
||||
* Wed Apr 06 2005 <duncan@iceblink.org> 1.8.1-1
|
||||
- Install ipmievd into /usr/sbin
|
||||
|
||||
* Wed Mar 16 2005 <duncan@iceblink.org> 1.8.0-1
|
||||
- Fix IPMIv2.0 issues
|
||||
- Fix chassis boot parameter support
|
||||
- Add support for linear sensors
|
||||
- Update bmc plugin to work with new Solaris bmc driver (new ioctl
|
||||
for interface detection and new STREAMS message-based interface)
|
||||
|
||||
* Tue Jan 18 2005 <duncan@iceblink.org> 1.7.0-1
|
||||
- Propogate errors correctly so exit status will be useful
|
||||
- More consistent display of errors including completion code text
|
||||
- Errors and debug is send to stderr now
|
||||
- New "sel get" command that will print details about SEL entry
|
||||
and corresponding SDR records as well as FRUs via entity association
|
||||
- Improved event generator, now supports reading events from text file
|
||||
- New "-o oemtype" option for specifying OEM boards
|
||||
exsting types are "supermicro" and "intelwv2"
|
||||
- New PEF subsystem from Tim Murphy at Dell
|
||||
- New "bmc" plugin for Solaris 10 x86
|
||||
- Many bugfixes and contributed patches
|
||||
- Support for Supermicro BMC OEM authentication method
|
||||
- Fix minor problem with LAN parameter setting
|
||||
|
||||
* Wed Aug 18 2004 <duncan@iceblink.org> 1.6.0-1
|
||||
- Add a README
|
||||
- Add support for IPMIv2 and Serial-over-LAN from Newisys
|
||||
|
@ -4,7 +4,7 @@ ARCH="@ARCH@"
|
||||
VERSION="@VERSION@"
|
||||
CATEGORY="system"
|
||||
VENDOR="Duncan Laurie"
|
||||
EMAIL="duncan@sun.com"
|
||||
EMAIL="duncan@iceblink.org"
|
||||
PSTAMP="@PSTAMP@"
|
||||
BASEDIR="@BASEDIR@"
|
||||
CLASSES="none"
|
||||
|
@ -1,7 +1,12 @@
|
||||
i pkginfo
|
||||
d none bin ? ? ?
|
||||
f none bin/@PACKAGE@=../src/@PACKAGE@ 0755 root bin
|
||||
d none sbin ? ? ?
|
||||
f none sbin/ipmievd=../src/ipmievd 0755 root bin
|
||||
d none share ? ? ?
|
||||
d none share/man ? ? ?
|
||||
d none share/man/man1 ? ? ?
|
||||
f none share/man/man1/@PACKAGE@.1=../doc/@PACKAGE@.1 0644 root bin
|
||||
d none share/man/man8 ? ? ?
|
||||
f none share/man/man8/ipmievd.8=../doc/ipmievd.8 0644 root bin
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
%_buildroot %{_topdir}/%{_tmppath}/%{name}-%{version}-root
|
||||
%_rpmdir %{_topdir}/RPMS
|
||||
%_srcrpmdir %{_topdir}/SRPMS
|
||||
%_distro @DISTRO@
|
||||
%_rpmfilename %%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm
|
||||
%packager duncan@iceblink.org
|
||||
%distribution Sourceforge Build
|
@ -1 +1,8 @@
|
||||
macrofiles: /usr/lib/rpm/macros:/usr/lib/rpm/%{_target}/macros:/etc/rpm/macros.specspo:/etc/rpm/macros:/etc/rpm/%{_target}/macros:%(echo $CONFIGDIR)/rpmmacros
|
||||
|
||||
buildarchtranslate: athlon: i386
|
||||
buildarchtranslate: i686: i386
|
||||
buildarchtranslate: i586: i386
|
||||
buildarchtranslate: i486: i386
|
||||
buildarchtranslate: i386: i386
|
||||
|
||||
|
5
ipmitool/debian/README.Debian
Normal file
5
ipmitool/debian/README.Debian
Normal file
@ -0,0 +1,5 @@
|
||||
For more information about setting up your Debian system with IPMI
|
||||
please see the excellent howto by Tim Small:
|
||||
|
||||
http://buttersideup.com/docs/howto/IPMI_on_Debian.html
|
||||
|
@ -1,3 +1,68 @@
|
||||
ipmitool (1.8.2-1) unstable; urgency=low
|
||||
|
||||
* New upstream release.
|
||||
- Fix FRU reading for large (>255 bytes) areas.
|
||||
- Overhaul to ipmievd to support SEL polling in addition to OpenIPMI.
|
||||
- Fix LAN parameter segfault when no Ciphers supported by
|
||||
BMC. (Closes: #306806)
|
||||
- Fix IPMIv2 support on Intel v2 BMCs (use -o intelplus).
|
||||
- Separate option parsing code from main ipmitool source file.
|
||||
- Add raw I2C support with IPMI Master Read-Write command.
|
||||
- Add support for new 'sdr elist' extended output format.
|
||||
- Add support for listing sensors by type with 'sdr type' command.
|
||||
- Add support for new 'sel elist' extended output format that
|
||||
cross-references events with sensors.
|
||||
- Add support for sending dynamically generated platform events
|
||||
based on existing sensor information.
|
||||
- New '-S' argument to read local SDR cache created with 'sdr dump'.
|
||||
- Updated manpage for ipmitool and ipmievd. (Closes: #306894)
|
||||
* Correct the upstream URL in debian/changelog to the current one.
|
||||
* Suggest package openipmi. (Closes: #305629)
|
||||
* Add debian/watch file to detect new source versions.
|
||||
|
||||
-- Petter Reinholdtsen <pere@debian.org> Sun, 5 Jun 2005 10:29:18 +0200
|
||||
|
||||
ipmitool (1.8.1-1) unstable; urgency=low
|
||||
|
||||
* New upstream release.
|
||||
* Install ipmievd into /usr/sbin/.
|
||||
|
||||
-- Petter Reinholdtsen <pere@debian.org> Thu, 7 Apr 2005 01:18:44 +0200
|
||||
|
||||
ipmitool (1.8.0-1) unstable; urgency=low
|
||||
|
||||
* Initial upload into Debian, based on the upstream build
|
||||
rules. (Closes: #299924)
|
||||
* Convert debian/changelog to UTF-8.
|
||||
* Change section from 'contrib' to 'utils'.
|
||||
* Build-depend on debhelper (>> 4.0.0) to match the rules file.
|
||||
* Set Standards-version to 3.6.1.
|
||||
* Make sure binary dependency is properly generated.
|
||||
* Add long description, copied from the project README.
|
||||
* Drop useless provides 'ipmitool', as the package is called 'ipmitool'.
|
||||
* Don't install the COPYING file, as the license text already is
|
||||
included in debian/copyright.
|
||||
* Remove unused parts of the rules file.
|
||||
* Correct clean target in rules file, to use 'distclean' and remove
|
||||
configure-stamp not bogus config-stamp.
|
||||
|
||||
-- Petter Reinholdtsen <pere@debian.org> Sun, 3 Apr 2005 20:52:02 +0200
|
||||
|
||||
ipmitool (1.8.0) unstable; urgency=low
|
||||
|
||||
* Fix IPMIv2.0 issues
|
||||
* Fix chassis boot parameter support
|
||||
* Add support for linear sensors
|
||||
|
||||
-- Duncan Laurie <duncan@iceblink.org> Wed, Mar 16 2005 17:08:12 -0700
|
||||
|
||||
ipmitool (1.7.1) unstable; urgency=low
|
||||
|
||||
* Update bmc plugin to work with new Solaris bmc driver (new ioctl
|
||||
for interface detection and new STREAMS message-based interface).
|
||||
|
||||
-- Seth Goldberg <sethmeisterg@hotmail.com> Mon, Mar 7 2005 18:03:00 -0800
|
||||
|
||||
ipmitool (1.7.0) unstable; urgency=low
|
||||
|
||||
* Propogate errors correctly so exit status will be useful
|
||||
@ -55,7 +120,7 @@ ipmitool (1.5.9) unstable; urgency=low
|
||||
* Add configure option for changing binary to ipmiadm for Solaris
|
||||
* Fix compile problem on Solaris 8
|
||||
|
||||
-- Duncan Laurie <duncan@sun.com> Sat, 27 Mar 2004 00:11:37 -0700
|
||||
-- Duncan Laurie <duncan@iceblink.org> Sat, 27 Mar 2004 00:11:37 -0700
|
||||
|
||||
ipmitool (1.5.8) unstable; urgency=low
|
||||
|
||||
@ -69,7 +134,7 @@ ipmitool (1.5.8) unstable; urgency=low
|
||||
* Add support for Linux kernel panic messages in SEL output
|
||||
* Add support for type 3 SDR records
|
||||
|
||||
-- Duncan Laurie <duncan@sun.com> Tue, 27 Jan 2004 16:23:25 -0700
|
||||
-- Duncan Laurie <duncan@iceblink.org> Tue, 27 Jan 2004 16:23:25 -0700
|
||||
|
||||
ipmitool (1.5.7) unstable; urgency=low
|
||||
|
||||
@ -78,49 +143,49 @@ ipmitool (1.5.7) unstable; urgency=low
|
||||
* better handling of SDR printing
|
||||
* contrib scripts for creating rrdtool graphs
|
||||
|
||||
-- Duncan Laurie <duncan@sun.com> Mon, 5 Jan 2004 17:29:50 -0700
|
||||
-- Duncan Laurie <duncan@iceblink.org> Mon, 5 Jan 2004 17:29:50 -0700
|
||||
|
||||
ipmitool (1.5.6) unstable; urgency=low
|
||||
|
||||
* Fix SEL event decoding for generic events
|
||||
* Handle empty SEL gracefully when doing "sel list"
|
||||
* Fix sdr handling of sensors that do not return a reading
|
||||
* Fix for CSV display of sensor readings/units from Fredrik <EFBFBD>hrn
|
||||
* Fix for CSV display of sensor readings/units from Fredrik Öhrn
|
||||
|
||||
-- Duncan Laurie <duncan@sun.com> Thu, 4 Dec 2003 14:47:19 -0700
|
||||
-- Duncan Laurie <duncan@iceblink.org> Thu, 4 Dec 2003 14:47:19 -0700
|
||||
|
||||
ipmitool (1.5.5) unstable; urgency=low
|
||||
|
||||
* Add -U option for setting LAN username
|
||||
* Fix -v usage for plugin interfaces
|
||||
|
||||
-- Duncan Laurie <duncan@sun.com> Tue, 25 Nov 2003 15:10:48 -0700
|
||||
-- Duncan Laurie <duncan@iceblink.org> Tue, 25 Nov 2003 15:10:48 -0700
|
||||
|
||||
ipmitool (1.5.4) unstable; urgency=low
|
||||
|
||||
* Put interface plugin API into library
|
||||
* Fix ipmievd
|
||||
|
||||
-- Duncan Laurie <duncan@sun.com> Fri, 14 Nov 2003 15:16:34 -0700
|
||||
-- Duncan Laurie <duncan@iceblink.org> Fri, 14 Nov 2003 15:16:34 -0700
|
||||
|
||||
ipmitool (1.5.3) unstable; urgency=low
|
||||
|
||||
* Add -g option to work with grizzly bmc
|
||||
|
||||
-- Duncan Laurie <duncan@sun.com> Mon, 3 Nov 2003 18:04:07 -0700
|
||||
-- Duncan Laurie <duncan@iceblink.org> Mon, 3 Nov 2003 18:04:07 -0700
|
||||
|
||||
ipmitool (1.5.2) unstable; urgency=low
|
||||
|
||||
* add support for setting gratuitous arp interval
|
||||
|
||||
-- Duncan Laurie <duncan@sun.com> Fri, 24 Oct 2003 11:00:00 -0700
|
||||
-- Duncan Laurie <duncan@iceblink.org> Fri, 24 Oct 2003 11:00:00 -0700
|
||||
|
||||
ipmitool (1.5.1) unstable; urgency=low
|
||||
|
||||
* better SEL support
|
||||
* fix display bug in SDR list
|
||||
|
||||
-- Duncan Laurie <duncan@sun.com> Wed, 8 Oct 2003 17:28:51 -0700
|
||||
-- Duncan Laurie <duncan@iceblink.org> Wed, 8 Oct 2003 17:28:51 -0700
|
||||
|
||||
ipmitool (1.5.0) unstable; urgency=low
|
||||
|
||||
@ -128,24 +193,24 @@ ipmitool (1.5.0) unstable; urgency=low
|
||||
* add Intel IMB driver support
|
||||
* use autoconf/automake/libtool
|
||||
|
||||
-- Duncan Laurie <duncan@sun.com> Fri, 5 Sep 2003 11:57:32 -0700
|
||||
-- Duncan Laurie <duncan@iceblink.org> Fri, 5 Sep 2003 11:57:32 -0700
|
||||
|
||||
ipmitool (1.2-1) unstable; urgency=low
|
||||
|
||||
* New command line option parsing
|
||||
* More chassis commands supported
|
||||
|
||||
-- Duncan Laurie <duncan@sun.com> Wed, 2 Apr 2003 17:44:17 -0700
|
||||
-- Duncan Laurie <duncan@iceblink.org> Wed, 2 Apr 2003 17:44:17 -0700
|
||||
|
||||
ipmitool (1.1-1) unstable; urgency=low
|
||||
|
||||
* Minor fixes.
|
||||
|
||||
-- Duncan Laurie <duncan@sun.com> Tue, 1 Apr 2003 14:31:10 -0700
|
||||
-- Duncan Laurie <duncan@iceblink.org> Tue, 1 Apr 2003 14:31:10 -0700
|
||||
|
||||
ipmitool (1.0-1) unstable; urgency=low
|
||||
|
||||
* Initial Release.
|
||||
|
||||
-- Duncan Laurie <duncan@sun.com> Sun, 30 Mar 2003 21:30:46 -0700
|
||||
-- Duncan Laurie <duncan@iceblink.org> Sun, 30 Mar 2003 21:30:46 -0700
|
||||
|
||||
|
@ -1,12 +1,28 @@
|
||||
Source: ipmitool
|
||||
Section: contrib
|
||||
Section: utils
|
||||
Priority: optional
|
||||
Maintainer: Duncan Laurie <duncan@iceblink.org>
|
||||
Build-Depends: debhelper (>> 3.0.0)
|
||||
Standards-Version: 3.5.8
|
||||
Maintainer: Petter Reinholdtsen <pere@debian.org>
|
||||
Uploaders: Duncan Laurie <duncan@iceblink.org>
|
||||
Build-Depends: debhelper (>> 4.0.0),
|
||||
Standards-Version: 3.6.1
|
||||
|
||||
Package: ipmitool
|
||||
Architecture: i386 amd64
|
||||
Provides: ipmitool
|
||||
Description: Utility for IPMI control with kernel driver or LAN interface
|
||||
Depends: ${shlibs:Depends}
|
||||
Suggest: openipmi
|
||||
Description: utility for IPMI control with kernel driver or LAN interface
|
||||
A utility for managing and configuring devices that support the
|
||||
Intelligent Platform Management Interface. IPMI is an open standard
|
||||
for monitoring, logging, recovery, inventory, and control of hardware
|
||||
that is implemented independent of the main CPU, BIOS, and OS. The
|
||||
service processor (or Baseboard Management Controller, BMC) is the
|
||||
brain behind platform management and its primary purpose is to handle
|
||||
the autonomous sensor monitoring and event logging features.
|
||||
.
|
||||
The ipmitool program provides a simple command-line interface to this
|
||||
BMC. It features the ability to read the sensor data repository
|
||||
(SDR) and print sensor values, display the contents of the System
|
||||
Event Log (SEL), print Field Replaceable Unit (FRU) inventory
|
||||
information, read and set LAN configuration parameters, and perform
|
||||
remote chassis power control.
|
||||
|
||||
|
@ -1,6 +1,9 @@
|
||||
ipmitool
|
||||
Duncan Laurie <duncan@sun.com>
|
||||
http://www.iceblink.org/ipmitool/
|
||||
This package was debianized by Duncan Laurie before
|
||||
2003-11-18 17:55:21 +0100.
|
||||
|
||||
It was downloaded from <URL:http://ipmitool.sourceforge.net/>
|
||||
|
||||
Upstream Author: Duncan Laurie <duncan@iceblink.org>
|
||||
|
||||
Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
|
||||
|
||||
@ -35,4 +38,3 @@ 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.
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
usr/bin
|
||||
usr/sbin
|
||||
usr/share/ipmitool
|
||||
usr/share/doc/ipmitool
|
||||
|
@ -1,4 +1,2 @@
|
||||
README
|
||||
COPYING
|
||||
AUTHORS
|
||||
ChangeLog
|
||||
|
@ -41,10 +41,10 @@ build-indep-stamp: configure-stamp
|
||||
clean:
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
rm -f build-arch-stamp build-indep-stamp config-stamp
|
||||
rm -f build-arch-stamp build-indep-stamp configure-stamp
|
||||
|
||||
# Add here commands to clean up after the build process.
|
||||
-$(MAKE) clean
|
||||
-$(MAKE) distclean
|
||||
|
||||
dh_clean
|
||||
|
||||
@ -71,6 +71,17 @@ install-arch:
|
||||
# debian/tmp.
|
||||
$(MAKE) install DESTDIR=$(CURDIR)/debian/ipmitool
|
||||
|
||||
# No need to have two copies of the license text in the package.
|
||||
$(RM) $(CURDIR)/debian/ipmitool/usr/share/doc/ipmitool/COPYING
|
||||
|
||||
# Move upstream changelog to correct filename.
|
||||
mv $(CURDIR)/debian/ipmitool/usr/share/doc/ipmitool/ChangeLog \
|
||||
$(CURDIR)/debian/ipmitool/usr/share/doc/ipmitool/changelog
|
||||
|
||||
# Compress to avoid lintian warning. Not sure why dh_compress
|
||||
# isn't fixing this.
|
||||
gzip -9 $(CURDIR)/debian/ipmitool/usr/share/doc/ipmitool/changelog
|
||||
|
||||
# dh_movefiles -a
|
||||
# Must not depend on anything. This is to be called by
|
||||
# binary-arch/binary-multi
|
||||
@ -78,27 +89,15 @@ install-arch:
|
||||
binary-common:
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
# dh_installdebconf
|
||||
dh_installdocs
|
||||
# dh_installexamples
|
||||
# dh_installmenu
|
||||
# dh_installemacsen
|
||||
# dh_installpam
|
||||
# dh_installinit
|
||||
# dh_installcron
|
||||
# dh_installmanpages
|
||||
# dh_installinfo
|
||||
# dh_undocumented
|
||||
# dh_installchangelogs
|
||||
dh_installchangelogs
|
||||
dh_link
|
||||
dh_strip
|
||||
dh_compress
|
||||
dh_fixperms
|
||||
# You may want to make some executables suid here.
|
||||
# dh_suidregister
|
||||
dh_makeshlibs
|
||||
dh_shlibdeps
|
||||
dh_installdeb
|
||||
# dh_perl
|
||||
dh_gencontrol
|
||||
dh_md5sums
|
||||
dh_builddeb
|
||||
|
6
ipmitool/debian/watch
Normal file
6
ipmitool/debian/watch
Normal file
@ -0,0 +1,6 @@
|
||||
# Rename this file to "watch" and then you can run the "uscan" command
|
||||
# to check for upstream updates and more.
|
||||
# Site Directory Pattern Version Script
|
||||
version=2
|
||||
http://heanet.dl.sourceforge.net/sourceforge/ipmitool/ipmitool-(.*).tar.bz2
|
||||
# debian uupdate
|
@ -34,7 +34,7 @@
|
||||
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
||||
man_MANS = ipmitool.1
|
||||
man_MANS = ipmitool.1 ipmievd.8
|
||||
|
||||
EXTRA_DIST = $(man_MANS)
|
||||
|
||||
|
208
ipmitool/doc/ipmievd.8
Normal file
208
ipmitool/doc/ipmievd.8
Normal file
@ -0,0 +1,208 @@
|
||||
.TH "ipmievd" "8" "" "Duncan Laurie" ""
|
||||
.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]
|
||||
\fB\-I\fR \fIopen\fP <\fIopen\fR | \fIsel\fR> [<\fIoption\fP>]
|
||||
|
||||
ipmievd [\fB\-c\fR|\fB\-h\fR|\fB\-v\fR|\fB\-V\fR]
|
||||
\fB\-I\fR \fIlan\fP \fB\-H\fR <\fIhostname\fP>
|
||||
[\fB\-p\fR <\fIport\fP>]
|
||||
[\fB\-U\fR <\fIusername\fP>]
|
||||
[\fB\-A\fR <\fIauthtype\fP>]
|
||||
[\fB\-L\fR <\fIprivlvl\fP>]
|
||||
[\fB\-a\fR|\fB\-E\fR|\fB\-P\fR|\fB\-f\fR <\fIpassword\fP>]
|
||||
[\fB\-o\fR <\fIoemtype\fP>]
|
||||
\fIsel\fP [<\fIoption\fP>]
|
||||
|
||||
ipmievd [\fB\-c\fR|\fB\-h\fR|\fB\-v\fR|\fB\-V\fR]
|
||||
\fB\-I\fR \fIlanplus\fP \fB\-H\fR <\fIhostname\fP>
|
||||
[\fB\-p\fR <\fIport\fP>]
|
||||
[\fB\-U\fR <\fIusername\fP>]
|
||||
[\fB\-L\fR <\fIprivlvl\fP>]
|
||||
[\fB\-a\fR|\fB\-E\fR|\fB\-P\fR|\fB\-f\fR <\fIpassword\fP>]
|
||||
[\fB\-o\fR <\fIoemtype\fP>]
|
||||
[\fB\-C\fR <\fIciphersuite\fP>]
|
||||
\fIsel\fR [<\fIoption\fP>]
|
||||
.SH "DESCRIPTION"
|
||||
\fBipmievd\fP is a daemon which will listen for events from the
|
||||
BMC that are being sent to the SEL and also log those messages to
|
||||
syslog. It is able to run in one of two modes: either using the
|
||||
Event Message Buffer and asynchronous event notification from the
|
||||
OpenIPMI kernel driver or actively polling the contents of the
|
||||
SEL for new events. Upon receipt of an event via either mechanism
|
||||
it will be logged to syslog with the \fILOG_LOCAL4\fP facility.
|
||||
|
||||
It is based on the \fBipmitool\fR utility and shares the same IPMI
|
||||
interface support and session setup options. Please see the
|
||||
\fBipmitool\fR manpage for more information on supported IPMI
|
||||
interfaces.
|
||||
.SH "OPTIONS"
|
||||
.TP
|
||||
\fB\-a\fR
|
||||
Prompt for the remote server password.
|
||||
.TP
|
||||
\fB\-A\fR <\fIauthtype\fP>
|
||||
Specify an authentication type to use during IPMIv1.5 \fIlan\fP
|
||||
session activation. Supported types are NONE, PASSWORD, MD5, or OEM.
|
||||
.TP
|
||||
\fB\-c\fR
|
||||
Present output in CSV (comma separated variable) format.
|
||||
This is not available with all commands.
|
||||
.TP
|
||||
\fB\-C\fR <\fIciphersuite\fP>
|
||||
The remote server authentication, integrity, and encryption algorithms
|
||||
to use for IPMIv2 \fIlanplus\fP connections. See table 22\-19 in the
|
||||
IPMIv2 specification. The default is 3 which specifies RAKP\-HMAC\-SHA1
|
||||
authentication, HMAC\-SHA1\-96 integrity, and AES\-CBC\-128 encryption algorightms.
|
||||
.TP
|
||||
\fB\-E\fR
|
||||
The remote server password is specified by the environment
|
||||
variable \fIIPMI_PASSWORD\fP.
|
||||
.TP
|
||||
\fB\-f\fR <\fIpassword_file\fP>
|
||||
Specifies a file containing the remote server password. If this
|
||||
option is absent, or if password_file is empty, the password
|
||||
will default to NULL.
|
||||
.TP
|
||||
\fB\-h\fR
|
||||
Get basic usage help from the command line.
|
||||
.TP
|
||||
\fB\-H\fR <\fIaddress\fP>
|
||||
Remote server address, can be IP address or hostname. This
|
||||
option is required for \fIlan\fP and \fIlanplus\fP interfaces.
|
||||
.TP
|
||||
\fB\-I\fR <\fIinterface\fP>
|
||||
Selects IPMI interface to use. Supported interfaces that are
|
||||
compiled in are visible in the usage help output.
|
||||
.TP
|
||||
\fB\-L\fR <\fIprivlvl\fP>
|
||||
Force session privilege level. Can be CALLBACK, USER,
|
||||
OPERATOR, ADMIN. Default is ADMIN.
|
||||
.TP
|
||||
\fB\-m\fR <\fIlocal_address\fP>
|
||||
Set the local IPMB address. The default is 0x20 and there
|
||||
should be no need to change it for normal operation.
|
||||
.TP
|
||||
\fB\-o\fR <\fIoemtype\fP>
|
||||
Select OEM type to support. This usually involves minor hacks
|
||||
in place in the code to work around quirks in various BMCs from
|
||||
various manufacturers. Use \fI\-o list\fP to see a list of
|
||||
current supported OEM types.
|
||||
.TP
|
||||
\fB\-p\fR <\fIport\fP>
|
||||
Remote server UDP port to connect to. Default is 623.
|
||||
.TP
|
||||
\fB\-P\fR <\fIpassword\fP>
|
||||
Remote server password is specified on the command line.
|
||||
If supported it will be obscured in the process list.
|
||||
\fBNote!\fR Specifying the password as a command line
|
||||
option is not recommended.
|
||||
.TP
|
||||
\fB\-S\fR <\fIsdr_cache_file\fP>
|
||||
Use local file for remote SDR cache. Using a local SDR cache
|
||||
can drastically increase performance for commands that require
|
||||
knowledge of the entire SDR to perform their function.
|
||||
.TP
|
||||
\fB\-t\fR <\fItarget_address\fP>
|
||||
Bridge IPMI requests to the remote target address.
|
||||
.TP
|
||||
\fB\-U\fR <\fIusername\fP>
|
||||
Remote server username, default is NULL user.
|
||||
.TP
|
||||
\fB\-v\fR
|
||||
Increase verbose output level. This option may be specified
|
||||
multiple times to increase the level of debug output. If given
|
||||
three times you will get hexdumps of all incoming and
|
||||
outgoing packets.
|
||||
.TP
|
||||
\fB\-V\fR
|
||||
Display version information.
|
||||
|
||||
.LP
|
||||
If no password method is specified then ipmievd will prompt the
|
||||
user for a password. If no password is entered at the prompt,
|
||||
the remote server password will default to NULL.
|
||||
.SH "COMMANDS"
|
||||
.TP
|
||||
\fIhelp\fP
|
||||
This can be used to get command\-line help. It may also be
|
||||
placed at the end of commands to get option usage help.
|
||||
|
||||
> ipmievd help
|
||||
.br
|
||||
Commands:
|
||||
open Use OpenIPMI for asyncronous notification of events
|
||||
sel Poll SEL for notification of events
|
||||
|
||||
.TP
|
||||
\fIopen\fP
|
||||
This command starts ipmievd with the OpenIPMI event watching
|
||||
mechanism which relies on the Event Message Buffer feature of
|
||||
IPMI. This requires a properly installed and configured
|
||||
OpenIPMI driver on Linux and is only valid to be run through
|
||||
the \fIopen\fP interface. See the \fBipmitool\fR manpage
|
||||
and associated documentation for more information on setting
|
||||
up the OpenIPMI driver.
|
||||
|
||||
\fBNote\fR: Some BMC do not support the Event Message Buffer
|
||||
required for this command. Other BMCs claim to support it but
|
||||
do not actually deliver events to it. If this is the case please
|
||||
use the \fIsel\fP method.
|
||||
|
||||
.RS
|
||||
.TP
|
||||
\fIdaemon\fP
|
||||
Launch process as a daemon and reparent to init process.
|
||||
All messages will be sent to syslog. This is the default action.
|
||||
.TP
|
||||
\fInodaemon\fP
|
||||
Do NOT become a daemon, instead log all messages to stderr.
|
||||
.RE
|
||||
|
||||
.TP
|
||||
\fIsel\fP
|
||||
This command starts ipmievd with the SEL Polling event watching
|
||||
mechanism. This will poll the SEL periodically to determine if
|
||||
new events have been logged. This command should work with all
|
||||
BMCs and is capable of using the LAN interface as well to monitor
|
||||
a remote system and log its events to a local syslog.
|
||||
|
||||
.RS
|
||||
.TP
|
||||
\fIdaemon\fP
|
||||
Launch process as a daemon and reparent to init process.
|
||||
All messages will be sent to syslog. This is the default action.
|
||||
.TP
|
||||
\fInodaemon\fP
|
||||
Do NOT become a daemon, instead log all messages to stderr.
|
||||
.TP
|
||||
\fItimeout\fP=<\fBseconds\fR>
|
||||
Time between checks for SEL polling method. Default is 10 seconds.
|
||||
.RE
|
||||
.SH "EXAMPLES"
|
||||
.TP
|
||||
\fIExample 1\fP: Daemon process watching OpenIPMI for events
|
||||
|
||||
> ipmievd \-I open open daemon
|
||||
.TP
|
||||
\fIExample 2\fP: Local non\-daemon process checking remote SEL every 30 seconds
|
||||
|
||||
> ipmievd \-I lan \-H 1.2.3.4 \-f passfile sel nodaemon timeout=30
|
||||
.br
|
||||
Reading Sensors...
|
||||
.br
|
||||
Waiting for Events...
|
||||
.br
|
||||
.SH "AUTHOR"
|
||||
Duncan Laurie <duncan@iceblink.org>
|
||||
.SH "SEE ALSO"
|
||||
.TP
|
||||
IPMItool Homepage
|
||||
http://ipmitool.sourceforge.net
|
||||
.TP
|
||||
Intelligent Platform Management Interface Specification
|
||||
http://www.intel.com/design/servers/ipmi
|
||||
.TP
|
||||
OpenIPMI Homepage
|
||||
http://openipmi.sourceforge.net
|
File diff suppressed because it is too large
Load Diff
@ -39,5 +39,6 @@ noinst_HEADERS = log.h bswap.h helper.h ipmi.h ipmi_intf.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 \
|
||||
ipmi_oem.h
|
||||
ipmi_oem.h ipmi_isol.h ipmi_sunoem.h ipmi_picmg.h \
|
||||
ipmi_fwum.h ipmi_main.h ipmi_tsol.h
|
||||
|
||||
|
@ -41,6 +41,9 @@
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#undef BSWAP_16
|
||||
#undef BSWAP_32
|
||||
|
||||
#if HAVE_BYTESWAP_H
|
||||
# include <byteswap.h>
|
||||
# define BSWAP_16(x) bswap_16(x)
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
struct valstr {
|
||||
uint16_t val;
|
||||
@ -47,6 +48,9 @@ struct valstr {
|
||||
};
|
||||
const char * val2str(uint16_t val, const struct valstr * 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);
|
||||
|
||||
|
||||
uint16_t buf2short(uint8_t * buf);
|
||||
uint32_t buf2long(uint8_t * buf);
|
||||
@ -54,6 +58,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);
|
||||
|
||||
#define ipmi_open_file_read(file) ipmi_open_file(file, 0)
|
||||
#define ipmi_open_file_write(file) ipmi_open_file(file, 1)
|
||||
@ -62,4 +67,16 @@ FILE * ipmi_open_file(const char * file, int rw);
|
||||
# define __min(a, b) ((a) < (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#ifndef __max
|
||||
# define __max(a, b) ((a) > (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#ifndef __minlen
|
||||
# define __minlen(a, b) ({ int x=strlen(a); int y=strlen(b); (x < y) ? x : y;})
|
||||
#endif
|
||||
|
||||
#ifndef __maxlen
|
||||
# define __maxlen(a, b) ({ int x=strlen(a); int y=strlen(b); (x > y) ? x : y;})
|
||||
#endif
|
||||
|
||||
#endif /* IPMI_HELPER_H */
|
||||
|
@ -49,6 +49,7 @@
|
||||
/* From table 13.16 of the IPMI v2 specification */
|
||||
#define IPMI_PAYLOAD_TYPE_IPMI 0x00
|
||||
#define IPMI_PAYLOAD_TYPE_SOL 0x01
|
||||
#define IPMI_PAYLOAD_TYPE_OEM 0x02
|
||||
#define IPMI_PAYLOAD_TYPE_RMCP_OPEN_REQUEST 0x10
|
||||
#define IPMI_PAYLOAD_TYPE_RMCP_OPEN_RESPONSE 0x11
|
||||
#define IPMI_PAYLOAD_TYPE_RAKP_1 0x12
|
||||
@ -56,13 +57,13 @@
|
||||
#define IPMI_PAYLOAD_TYPE_RAKP_3 0x14
|
||||
#define IPMI_PAYLOAD_TYPE_RAKP_4 0x15
|
||||
|
||||
|
||||
extern int verbose;
|
||||
extern int csv_output;
|
||||
|
||||
struct ipmi_rq {
|
||||
struct {
|
||||
uint8_t netfn;
|
||||
uint8_t netfn:6;
|
||||
uint8_t lun:2;
|
||||
uint8_t cmd;
|
||||
uint8_t target_cmd;
|
||||
uint16_t data_len;
|
||||
@ -70,7 +71,6 @@ struct ipmi_rq {
|
||||
} msg;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* This is what the sendrcv_v2() function would take as an argument. The common case
|
||||
* is for payload_type to be IPMI_PAYLOAD_TYPE_IPMI.
|
||||
@ -83,37 +83,37 @@ struct ipmi_v2_payload {
|
||||
|
||||
struct {
|
||||
uint8_t rq_seq;
|
||||
struct ipmi_rq * request;
|
||||
struct ipmi_rq *request;
|
||||
} ipmi_request;
|
||||
|
||||
struct {
|
||||
uint8_t rs_seq;
|
||||
struct ipmi_rs * response;
|
||||
struct ipmi_rs *response;
|
||||
} ipmi_response;
|
||||
|
||||
/* Only used internally by the lanplus interface */
|
||||
struct {
|
||||
uint8_t * request;
|
||||
uint8_t *request;
|
||||
} open_session_request;
|
||||
|
||||
/* Only used internally by the lanplus interface */
|
||||
struct {
|
||||
uint8_t * message;
|
||||
uint8_t *message;
|
||||
} rakp_1_message;
|
||||
|
||||
/* Only used internally by the lanplus interface */
|
||||
struct {
|
||||
uint8_t * message;
|
||||
uint8_t *message;
|
||||
} rakp_2_message;
|
||||
|
||||
/* Only used internally by the lanplus interface */
|
||||
struct {
|
||||
uint8_t * message;
|
||||
uint8_t *message;
|
||||
} rakp_3_message;
|
||||
|
||||
/* Only used internally by the lanplus interface */
|
||||
struct {
|
||||
uint8_t * message;
|
||||
uint8_t *message;
|
||||
} rakp_4_message;
|
||||
|
||||
struct {
|
||||
@ -134,20 +134,15 @@ struct ipmi_v2_payload {
|
||||
} payload;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct ipmi_rq_entry {
|
||||
struct ipmi_rq req;
|
||||
struct ipmi_intf * intf;
|
||||
struct ipmi_intf *intf;
|
||||
uint8_t rq_seq;
|
||||
uint8_t * msg_data;
|
||||
uint8_t *msg_data;
|
||||
int msg_len;
|
||||
struct ipmi_rq_entry * next;
|
||||
struct ipmi_rq_entry *next;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
struct ipmi_rs {
|
||||
uint8_t ccode;
|
||||
uint8_t data[IPMI_BUF_SIZE];
|
||||
@ -178,7 +173,6 @@ struct ipmi_rs {
|
||||
uint16_t msglen;
|
||||
} session;
|
||||
|
||||
|
||||
/*
|
||||
* A union of the different possible payload meta-data
|
||||
*/
|
||||
@ -230,8 +224,6 @@ struct ipmi_rs {
|
||||
} payload;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#define IPMI_NETFN_CHASSIS 0x0
|
||||
#define IPMI_NETFN_BRIDGE 0x2
|
||||
#define IPMI_NETFN_SE 0x4
|
||||
@ -239,7 +231,9 @@ struct ipmi_rs {
|
||||
#define IPMI_NETFN_FIRMWARE 0x8
|
||||
#define IPMI_NETFN_STORAGE 0xa
|
||||
#define IPMI_NETFN_TRANSPORT 0xc
|
||||
#define IPMI_NETFN_PICMG 0x2C
|
||||
#define IPMI_NETFN_ISOL 0x34
|
||||
#define IPMI_NETFN_TSOL 0x30
|
||||
|
||||
#define IPMI_BMC_SLAVE_ADDR 0x20
|
||||
#define IPMI_REMOTE_SWID 0x81
|
||||
|
@ -42,6 +42,7 @@
|
||||
#endif
|
||||
#include <ipmitool/ipmi.h>
|
||||
|
||||
|
||||
#define IPMI_GET_CHANNEL_AUTH_CAP 0x38
|
||||
#define IPMI_GET_CHANNEL_ACCESS 0x41
|
||||
#define IPMI_GET_CHANNEL_INFO 0x42
|
||||
@ -50,6 +51,7 @@
|
||||
#define IPMI_SET_USER_NAME 0x45
|
||||
#define IPMI_GET_USER_NAME 0x46
|
||||
#define IPMI_SET_USER_PASSWORD 0x47
|
||||
#define IPMI_GET_CHANNEL_CIPHER_SUITES 0x54
|
||||
|
||||
|
||||
/*
|
||||
|
@ -51,6 +51,9 @@
|
||||
#define IPMI_CHASSIS_POLICY_PREVIOUS 0x1
|
||||
#define IPMI_CHASSIS_POLICY_ALWAYS_OFF 0x0
|
||||
|
||||
int ipmi_chassis_main(struct ipmi_intf *, int, char **);
|
||||
int ipmi_chassis_power_status(struct ipmi_intf * intf);
|
||||
int ipmi_chassis_power_control(struct ipmi_intf * intf, uint8_t ctl);
|
||||
int ipmi_chassis_main(struct ipmi_intf * intf, int argc, char ** argv);
|
||||
int ipmi_power_main(struct ipmi_intf * intf, int argc, char ** argv);
|
||||
|
||||
#endif /*IPMI_CHASSIS_H*/
|
||||
|
@ -70,6 +70,7 @@
|
||||
#define IPMI_SESSION_AUTHTYPE_OEM 0x5
|
||||
#define IPMI_SESSION_AUTHTYPE_RMCP_PLUS 0x6
|
||||
|
||||
#define IPMI_SESSION_PRIV_UNSPECIFIED 0x0
|
||||
#define IPMI_SESSION_PRIV_CALLBACK 0x1
|
||||
#define IPMI_SESSION_PRIV_USER 0x2
|
||||
#define IPMI_SESSION_PRIV_OPERATOR 0x3
|
||||
@ -81,7 +82,7 @@
|
||||
#define IPMI_SET_IN_PROGRESS_COMMIT_WRITE 0x02
|
||||
|
||||
#define IPMI_CHANNEL_MEDIUM_RESERVED 0x0
|
||||
#define IPMI_CHANNEL_MEDIUM_IPMB 0x1
|
||||
#define IPMI_CHANNEL_MEDIUM_IPMB_I2C 0x1
|
||||
#define IPMI_CHANNEL_MEDIUM_ICMB_1 0x2
|
||||
#define IPMI_CHANNEL_MEDIUM_ICMB_09 0x3
|
||||
#define IPMI_CHANNEL_MEDIUM_LAN 0x4
|
||||
@ -94,4 +95,33 @@
|
||||
#define IPMI_CHANNEL_MEDIUM_USB_2 0xb
|
||||
#define IPMI_CHANNEL_MEDIUM_SYSTEM 0xc
|
||||
|
||||
#define IPMI_CHASSIS_CTL_POWER_DOWN 0x0
|
||||
#define IPMI_CHASSIS_CTL_POWER_UP 0x1
|
||||
#define IPMI_CHASSIS_CTL_POWER_CYCLE 0x2
|
||||
#define IPMI_CHASSIS_CTL_HARD_RESET 0x3
|
||||
#define IPMI_CHASSIS_CTL_PULSE_DIAG 0x4
|
||||
#define IPMI_CHASSIS_CTL_ACPI_SOFT 0x5
|
||||
|
||||
#define IPMI_CHASSIS_POLICY_NO_CHANGE 0x3
|
||||
#define IPMI_CHASSIS_POLICY_ALWAYS_ON 0x2
|
||||
#define IPMI_CHASSIS_POLICY_PREVIOUS 0x1
|
||||
#define IPMI_CHASSIS_POLICY_ALWAYS_OFF 0x0
|
||||
|
||||
/* From table 13-17 of the IPMI v2 specification */
|
||||
#define IPMI_AUTH_RAKP_NONE 0x00
|
||||
#define IPMI_AUTH_RAKP_HMAC_SHA1 0x01
|
||||
#define IPMI_AUTH_RAKP_HMAC_MD5 0x02
|
||||
|
||||
/* From table 13-18 of the IPMI v2 specification */
|
||||
#define IPMI_INTEGRITY_NONE 0x00
|
||||
#define IPMI_INTEGRITY_HMAC_SHA1_96 0x01
|
||||
#define IPMI_INTEGRITY_HMAC_MD5_128 0x02
|
||||
#define IPMI_INTEGRITY_MD5_128 0x03
|
||||
|
||||
/* From table 13-19 of the IPMI v2 specfication */
|
||||
#define IPMI_CRYPT_NONE 0x00
|
||||
#define IPMI_CRYPT_AES_CBC_128 0x01
|
||||
#define IPMI_CRYPT_XRC4_128 0x02
|
||||
#define IPMI_CRYPT_XRC4_40 0x03
|
||||
|
||||
#endif /*IPMI_CONSTANTS_H*/
|
||||
|
@ -42,6 +42,23 @@
|
||||
#endif
|
||||
#include <ipmitool/ipmi.h>
|
||||
|
||||
#define EVENT_DIR_ASSERT 0
|
||||
#define EVENT_DIR_DEASSERT 1
|
||||
|
||||
struct platform_event_msg {
|
||||
uint8_t evm_rev;
|
||||
uint8_t sensor_type;
|
||||
uint8_t sensor_num;
|
||||
#if WORDS_BIGENDIAN
|
||||
uint8_t event_dir : 1;
|
||||
uint8_t event_type : 7;
|
||||
#else
|
||||
uint8_t event_type : 7;
|
||||
uint8_t event_dir : 1;
|
||||
#endif
|
||||
uint8_t event_data[3];
|
||||
} __attribute__((packed));
|
||||
|
||||
int ipmi_event_main(struct ipmi_intf *, int, char **);
|
||||
|
||||
#endif /*IPMI_EVENT_H*/
|
||||
|
@ -66,7 +66,7 @@ enum {
|
||||
|
||||
struct fru_info {
|
||||
uint16_t size;
|
||||
uint8_t access : 1;
|
||||
uint8_t access:1;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct fru_header {
|
||||
@ -86,8 +86,8 @@ struct fru_area_chassis {
|
||||
uint8_t area_ver;
|
||||
uint8_t type;
|
||||
uint16_t area_len;
|
||||
char * part;
|
||||
char * serial;
|
||||
char *part;
|
||||
char *serial;
|
||||
};
|
||||
|
||||
struct fru_area_board {
|
||||
@ -95,24 +95,24 @@ struct fru_area_board {
|
||||
uint8_t lang;
|
||||
uint16_t area_len;
|
||||
uint32_t mfg_date_time;
|
||||
char * mfg;
|
||||
char * prod;
|
||||
char * serial;
|
||||
char * part;
|
||||
char * fru;
|
||||
char *mfg;
|
||||
char *prod;
|
||||
char *serial;
|
||||
char *part;
|
||||
char *fru;
|
||||
};
|
||||
|
||||
struct fru_area_product {
|
||||
uint8_t area_ver;
|
||||
uint8_t lang;
|
||||
uint16_t area_len;
|
||||
char * mfg;
|
||||
char * name;
|
||||
char * part;
|
||||
char * version;
|
||||
char * serial;
|
||||
char * asset;
|
||||
char * fru;
|
||||
char *mfg;
|
||||
char *name;
|
||||
char *part;
|
||||
char *version;
|
||||
char *serial;
|
||||
char *asset;
|
||||
char *fru;
|
||||
};
|
||||
|
||||
struct fru_multirec_header {
|
||||
@ -122,6 +122,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
|
||||
uint8_t type;
|
||||
uint8_t format;
|
||||
uint8_t len;
|
||||
@ -133,8 +134,8 @@ struct fru_multirec_powersupply {
|
||||
#if WORDS_BIGENDIAN
|
||||
uint16_t capacity;
|
||||
#else
|
||||
uint16_t capacity : 12;
|
||||
uint16_t __reserved1 : 4;
|
||||
uint16_t capacity:12;
|
||||
uint16_t __reserved1:4;
|
||||
#endif
|
||||
uint16_t peak_va;
|
||||
uint8_t inrush_current;
|
||||
@ -147,45 +148,44 @@ struct fru_multirec_powersupply {
|
||||
uint8_t highend_freq;
|
||||
uint8_t dropout_tolerance;
|
||||
#if WORDS_BIGENDIAN
|
||||
uint8_t __reserved2 : 3;
|
||||
uint8_t tach : 1;
|
||||
uint8_t hotswap : 1;
|
||||
uint8_t autoswitch : 1;
|
||||
uint8_t pfc : 1;
|
||||
uint8_t predictive_fail : 1;
|
||||
uint8_t __reserved2:3;
|
||||
uint8_t tach:1;
|
||||
uint8_t hotswap:1;
|
||||
uint8_t autoswitch:1;
|
||||
uint8_t pfc:1;
|
||||
uint8_t predictive_fail:1;
|
||||
#else
|
||||
uint8_t predictive_fail : 1;
|
||||
uint8_t pfc : 1;
|
||||
uint8_t autoswitch : 1;
|
||||
uint8_t hotswap : 1;
|
||||
uint8_t tach : 1;
|
||||
uint8_t __reserved2 : 3;
|
||||
uint8_t predictive_fail:1;
|
||||
uint8_t pfc:1;
|
||||
uint8_t autoswitch:1;
|
||||
uint8_t hotswap:1;
|
||||
uint8_t tach:1;
|
||||
uint8_t __reserved2:3;
|
||||
#endif
|
||||
uint16_t peak_cap_ht;
|
||||
#if WORDS_BIGENDIAN
|
||||
uint8_t combined_voltage1 : 4;
|
||||
uint8_t combined_voltage2 : 4;
|
||||
uint8_t combined_voltage1:4;
|
||||
uint8_t combined_voltage2:4;
|
||||
#else
|
||||
uint8_t combined_voltage2 : 4;
|
||||
uint8_t combined_voltage1 : 4;
|
||||
uint8_t combined_voltage2:4;
|
||||
uint8_t combined_voltage1:4;
|
||||
#endif
|
||||
uint16_t combined_capacity;
|
||||
uint8_t rps_threshold;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
static const char * combined_voltage_desc[] __attribute__((unused)) = {
|
||||
"12 V", "-12 V", "5 V", "3.3 V"
|
||||
};
|
||||
static const char *combined_voltage_desc[] __attribute__ ((unused)) = {
|
||||
"12 V", "-12 V", "5 V", "3.3 V"};
|
||||
|
||||
struct fru_multirec_dcoutput {
|
||||
#if WORDS_BIGENDIAN
|
||||
uint8_t standby : 1;
|
||||
uint8_t __reserved : 3;
|
||||
uint8_t output_number : 4;
|
||||
uint8_t standby:1;
|
||||
uint8_t __reserved:3;
|
||||
uint8_t output_number:4;
|
||||
#else
|
||||
uint8_t output_number : 4;
|
||||
uint8_t __reserved : 3;
|
||||
uint8_t standby : 1;
|
||||
uint8_t output_number:4;
|
||||
uint8_t __reserved:3;
|
||||
uint8_t standby:1;
|
||||
#endif
|
||||
short nominal_voltage;
|
||||
short max_neg_dev;
|
||||
@ -197,11 +197,11 @@ struct fru_multirec_dcoutput {
|
||||
|
||||
struct fru_multirec_dcload {
|
||||
#if WORDS_BIGENDIAN
|
||||
uint8_t __reserved : 4;
|
||||
uint8_t output_number : 4;
|
||||
uint8_t __reserved:4;
|
||||
uint8_t output_number:4;
|
||||
#else
|
||||
uint8_t output_number : 4;
|
||||
uint8_t __reserved : 4;
|
||||
uint8_t output_number:4;
|
||||
uint8_t __reserved:4;
|
||||
#endif
|
||||
short nominal_voltage;
|
||||
short min_voltage;
|
||||
@ -211,18 +211,112 @@ struct fru_multirec_dcload {
|
||||
uint16_t max_current;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
static const char * chassis_type_desc[] __attribute__((unused)) = {
|
||||
"Unspecified", "Other", "Unknown",
|
||||
struct fru_multirec_picmgext_header {
|
||||
unsigned char mfg_id[3];
|
||||
#define FRU_PICMG_BACKPLANE_P2P 0x04
|
||||
#define FRU_PICMG_ADDRESS_TABLE 0x10
|
||||
#define FRU_PICMG_SHELF_POWER_DIST 0x11
|
||||
#define FRU_PICMG_SHELF_ACTIVATION 0x12
|
||||
#define FRU_PICMG_SHMC_IP_CONN 0x13
|
||||
#define FRU_PICMG_BOARD_P2P 0x14
|
||||
#define FRU_AMC_CURRENT 0x16
|
||||
#define FRU_AMC_ACTIVATION 0x17
|
||||
#define FRU_AMC_CARRIER_P2P 0x18
|
||||
#define FRU_AMC_P2P 0x19
|
||||
#define FRU_AMC_CARRIER_INFO 0x1a
|
||||
unsigned char record_id;
|
||||
unsigned char record_version;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct fru_picmgext_guid {
|
||||
unsigned char guid[16];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct fru_picmgext_link_desc {
|
||||
#ifndef WORDS_BIGENDIAN
|
||||
unsigned int designator:12;
|
||||
#define FRU_PICMGEXT_LINK_TYPE_BASE 0x01
|
||||
#define FRU_PICMGEXT_LINK_TYPE_FABRIC_ETHERNET 0x02
|
||||
#define FRU_PICMGEXT_LINK_TYPE_FABRIC_INFINIBAND 0x03
|
||||
#define FRU_PICMGEXT_LINK_TYPE_FABRIC_STAR 0x04
|
||||
#define FRU_PICMGEXT_LINK_TYPE_PCIE 0x05
|
||||
unsigned int type:8;
|
||||
unsigned int ext:4;
|
||||
unsigned int grouping:8;
|
||||
#else
|
||||
unsigned int grouping:8;
|
||||
unsigned int ext:4;
|
||||
#define FRU_PICMGEXT_LINK_TYPE_BASE 0x01
|
||||
#define FRU_PICMGEXT_LINK_TYPE_FABRIC_ETHERNET 0x02
|
||||
#define FRU_PICMGEXT_LINK_TYPE_FABRIC_INFINIBAND 0x03
|
||||
#define FRU_PICMGEXT_LINK_TYPE_FABRIC_STAR 0x04
|
||||
#define FRU_PICMGEXT_LINK_TYPE_PCIE 0x05
|
||||
unsigned int type:8;
|
||||
unsigned int designator:12;
|
||||
#endif
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct fru_picmgext_chn_desc {
|
||||
#ifndef WORDS_BIGENDIAN
|
||||
unsigned char remote_slot:8;
|
||||
unsigned char remote_chn:5;
|
||||
unsigned char local_chn:5;
|
||||
unsigned char:6;
|
||||
#else
|
||||
unsigned char:6;
|
||||
unsigned char local_chn:5;
|
||||
unsigned char remote_chn:5;
|
||||
unsigned char remote_slot:8;
|
||||
#endif
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct fru_picmgext_slot_desc {
|
||||
unsigned char chan_type;
|
||||
unsigned char slot_addr;
|
||||
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_UPDATE_CHANNEL 0x02
|
||||
#define FRU_PICMGEXT_DESIGN_IF_RESERVED 0x03
|
||||
|
||||
struct fru_picmgext_activation_record {
|
||||
unsigned char ibmb_addr;
|
||||
unsigned char max_module_curr;
|
||||
unsigned char reserved;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct fru_picmgext_carrier_p2p_record {
|
||||
unsigned char resource_id;
|
||||
unsigned char p2p_count;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct fru_picmgext_carrier_p2p_descriptor {
|
||||
#ifndef WORDS_BIGENDIAN
|
||||
unsigned char remote_resource_id;
|
||||
unsigned short remote_port:5;
|
||||
unsigned short local_port:5;
|
||||
unsigned short reserved:6;
|
||||
#else
|
||||
unsigned short reserved:6;
|
||||
unsigned short local_port:5;
|
||||
unsigned short remote_port:5;
|
||||
unsigned char remote_resource_id;
|
||||
#endif
|
||||
} __attribute__ ((packed));
|
||||
|
||||
static const char *chassis_type_desc[] __attribute__ ((unused)) = {
|
||||
"Unspecified", "Other", "Unknown",
|
||||
"Desktop", "Low Profile Desktop", "Pizza Box",
|
||||
"Mini Tower", "Tower",
|
||||
"Portable", "LapTop", "Notebook", "Hand Held", "Docking Station",
|
||||
"All in One", "Sub Notebook", "Space-saving", "Lunch Box",
|
||||
"Main Server Chassis", "Expansion Chassis", "SubChassis",
|
||||
"Bus Expansion Chassis", "Peripheral Chassis", "RAID Chassis",
|
||||
"Rack Mount Chassis"
|
||||
};
|
||||
"Portable", "LapTop", "Notebook", "Hand Held",
|
||||
"Docking Station", "All in One", "Sub Notebook",
|
||||
"Space-saving", "Lunch Box", "Main Server Chassis",
|
||||
"Expansion Chassis", "SubChassis", "Bus Expansion Chassis",
|
||||
"Peripheral Chassis", "RAID Chassis", "Rack Mount Chassis"};
|
||||
|
||||
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_fru_main(struct ipmi_intf *intf, int argc, char **argv);
|
||||
int ipmi_fru_print(struct ipmi_intf *intf, struct sdr_record_fru_locator *fru);
|
||||
|
||||
#endif /* IPMI_FRU_H */
|
||||
|
46
ipmitool/include/ipmitool/ipmi_fwum.h
Normal file
46
ipmitool/include/ipmitool/ipmi_fwum.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef IPMI_KFWUM_H
|
||||
#define IPMI_KFWUM_H
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <ipmitool/ipmi.h>
|
||||
|
||||
|
||||
int ipmi_fwum_main(struct ipmi_intf *, int, char **);
|
||||
|
||||
#endif /* IPMI_KFWUM_H */
|
@ -68,7 +68,7 @@ enum LANPLUS_SESSION_STATE {
|
||||
|
||||
struct ipmi_session {
|
||||
uint8_t hostname[64];
|
||||
uint8_t username[16];
|
||||
uint8_t username[17];
|
||||
uint8_t authcode[IPMI_AUTHCODE_BUFFER_SIZE + 1];
|
||||
uint8_t challenge[16];
|
||||
uint8_t authtype;
|
||||
@ -81,9 +81,12 @@ struct ipmi_session {
|
||||
uint8_t authstatus;
|
||||
uint8_t authextra;
|
||||
uint8_t privlvl;
|
||||
uint8_t cipher_suite_id;
|
||||
char sol_escape_char;
|
||||
int password;
|
||||
int port;
|
||||
int active;
|
||||
int retry;
|
||||
|
||||
uint32_t session_id;
|
||||
uint32_t in_seq;
|
||||
@ -100,6 +103,9 @@ struct ipmi_session {
|
||||
enum LANPLUS_SESSION_STATE session_state;
|
||||
|
||||
/* These are the algorithms agreed upon for the session */
|
||||
uint8_t requested_auth_alg;
|
||||
uint8_t requested_integrity_alg;
|
||||
uint8_t requested_crypt_alg;
|
||||
uint8_t auth_alg;
|
||||
uint8_t integrity_alg;
|
||||
uint8_t crypt_alg;
|
||||
@ -144,17 +150,32 @@ struct ipmi_session {
|
||||
} sol_data;
|
||||
};
|
||||
|
||||
struct ipmi_cmd {
|
||||
int (*func)(struct ipmi_intf * intf, int argc, char ** argv);
|
||||
const char * name;
|
||||
const char * desc;
|
||||
};
|
||||
|
||||
struct ipmi_intf_support {
|
||||
const char * name;
|
||||
int supported;
|
||||
};
|
||||
|
||||
struct ipmi_intf {
|
||||
char name[16];
|
||||
char desc[128];
|
||||
int fd;
|
||||
int opened;
|
||||
int abort;
|
||||
int noanswer;
|
||||
|
||||
struct ipmi_session * session;
|
||||
struct ipmi_oem_handle * oem;
|
||||
struct ipmi_cmd * cmdlist;
|
||||
uint32_t my_addr;
|
||||
uint32_t target_addr;
|
||||
uint8_t target_lun;
|
||||
uint8_t target_channel;
|
||||
|
||||
int (*setup)(struct ipmi_intf * intf);
|
||||
int (*open)(struct ipmi_intf * intf);
|
||||
@ -167,14 +188,19 @@ struct ipmi_intf {
|
||||
};
|
||||
|
||||
struct ipmi_intf * ipmi_intf_load(char * name);
|
||||
void ipmi_intf_print(void);
|
||||
void ipmi_intf_print(struct ipmi_intf_support * intflist);
|
||||
|
||||
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_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);
|
||||
void ipmi_intf_session_set_port(struct ipmi_intf * intf, int port);
|
||||
void ipmi_intf_session_set_authtype(struct ipmi_intf * intf, uint8_t authtype);
|
||||
void ipmi_intf_session_set_timeout(struct ipmi_intf * intf, uint32_t timeout);
|
||||
void ipmi_intf_session_set_retry(struct ipmi_intf * intf, int retry);
|
||||
void ipmi_cleanup(struct ipmi_intf * intf);
|
||||
|
||||
#endif /* IPMI_INTF_H */
|
||||
|
60
ipmitool/include/ipmitool/ipmi_isol.h
Normal file
60
ipmitool/include/ipmitool/ipmi_isol.h
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef IPMI_ISOL_H
|
||||
#define IPMI_ISOL_H
|
||||
|
||||
#include <ipmitool/ipmi.h>
|
||||
|
||||
#define ACTIVATE_ISOL 0x01
|
||||
#define SET_ISOL_CONFIG 0x03
|
||||
#define GET_ISOL_CONFIG 0x04
|
||||
|
||||
#define ISOL_ENABLE_PARAM 0x01
|
||||
#define ISOL_AUTHENTICATION_PARAM 0x02
|
||||
#define ISOL_ENABLE_FLAG 0x01
|
||||
#define ISOL_PRIVILEGE_LEVEL_USER 0x02
|
||||
#define ISOL_BAUD_RATE_PARAM 0x05
|
||||
#define ISOL_BAUD_RATE_9600 0x06
|
||||
#define ISOL_BAUD_RATE_19200 0x07
|
||||
#define ISOL_BAUD_RATE_38400 0x08
|
||||
#define ISOL_BAUD_RATE_57600 0x09
|
||||
#define ISOL_BAUD_RATE_115200 0x0A
|
||||
#define ISOL_PREFERRED_BAUD_RATE 0x07
|
||||
|
||||
int ipmi_isol_main(struct ipmi_intf *, int, char **);
|
||||
|
||||
#endif /* IPMI_SOL_H */
|
@ -46,7 +46,7 @@
|
||||
# define IPMI_LAN_SUSPEND_ARP_GRAT (1)
|
||||
#define IPMI_LAN_GET_STAT 0x04
|
||||
|
||||
#define IPMI_CHANNEL_NUMBER_MAX 0xd
|
||||
#define IPMI_CHANNEL_NUMBER_MAX 0xe
|
||||
|
||||
#define IPMI_LANP_TIMEOUT 3
|
||||
#define IPMI_LANP_RETRIES 10
|
||||
@ -60,21 +60,26 @@ enum {
|
||||
IPMI_LANP_AUTH_TYPE_ENABLE,
|
||||
IPMI_LANP_IP_ADDR,
|
||||
IPMI_LANP_IP_ADDR_SRC,
|
||||
IPMI_LANP_MAC_ADDR,
|
||||
IPMI_LANP_MAC_ADDR, /* 5 */
|
||||
IPMI_LANP_SUBNET_MASK,
|
||||
IPMI_LANP_IP_HEADER,
|
||||
IPMI_LANP_PRI_RMCP_PORT,
|
||||
IPMI_LANP_SEC_RMCP_PORT,
|
||||
IPMI_LANP_BMC_ARP,
|
||||
IPMI_LANP_BMC_ARP, /* 10 */
|
||||
IPMI_LANP_GRAT_ARP,
|
||||
IPMI_LANP_DEF_GATEWAY_IP,
|
||||
IPMI_LANP_DEF_GATEWAY_MAC,
|
||||
IPMI_LANP_BAK_GATEWAY_IP,
|
||||
IPMI_LANP_BAK_GATEWAY_MAC,
|
||||
IPMI_LANP_BAK_GATEWAY_MAC, /* 15 */
|
||||
IPMI_LANP_SNMP_STRING,
|
||||
IPMI_LANP_NUM_DEST,
|
||||
IPMI_LANP_DEST_TYPE,
|
||||
IPMI_LANP_DEST_ADDR,
|
||||
IPMI_LANP_VLAN_ID, /* 20 */
|
||||
IPMI_LANP_VLAN_PRIORITY,
|
||||
IPMI_LANP_RMCP_CIPHER_SUPPORT,
|
||||
IPMI_LANP_RMCP_CIPHERS,
|
||||
IPMI_LANP_RMCP_PRIV_LEVELS,
|
||||
IPMI_LANP_OEM_ALERT_STRING=96,
|
||||
IPMI_LANP_ALERT_RETRY=97,
|
||||
IPMI_LANP_UTC_OFFSET=98,
|
||||
@ -96,27 +101,32 @@ static struct lan_param {
|
||||
{ IPMI_LANP_AUTH_TYPE_ENABLE, 5, "Auth Type Enable" },
|
||||
{ IPMI_LANP_IP_ADDR, 4, "IP Address" },
|
||||
{ IPMI_LANP_IP_ADDR_SRC, 1, "IP Address Source" },
|
||||
{ IPMI_LANP_MAC_ADDR, 6, "MAC Address" },
|
||||
{ IPMI_LANP_MAC_ADDR, 6, "MAC Address" }, /* 5 */
|
||||
{ IPMI_LANP_SUBNET_MASK, 4, "Subnet Mask" },
|
||||
{ IPMI_LANP_IP_HEADER, 3, "IP Header" },
|
||||
{ IPMI_LANP_PRI_RMCP_PORT, 2, "Primary RMCP Port" },
|
||||
{ IPMI_LANP_SEC_RMCP_PORT, 2, "Secondary RMCP Port" },
|
||||
{ IPMI_LANP_BMC_ARP, 1, "BMC ARP Control" },
|
||||
{ IPMI_LANP_BMC_ARP, 1, "BMC ARP Control" }, /* 10 */
|
||||
{ IPMI_LANP_GRAT_ARP, 1, "Gratituous ARP Intrvl" },
|
||||
{ IPMI_LANP_DEF_GATEWAY_IP, 4, "Default Gateway IP" },
|
||||
{ IPMI_LANP_DEF_GATEWAY_MAC, 6, "Default Gateway MAC" },
|
||||
{ IPMI_LANP_BAK_GATEWAY_IP, 4, "Backup Gateway IP" },
|
||||
{ IPMI_LANP_BAK_GATEWAY_MAC, 6, "Backup Gateway MAC" },
|
||||
{ IPMI_LANP_BAK_GATEWAY_MAC, 6, "Backup Gateway MAC" }, /* 15 */
|
||||
{ IPMI_LANP_SNMP_STRING, 18, "SNMP Community String" },
|
||||
{ IPMI_LANP_NUM_DEST, 1, "Number of Destinations"},
|
||||
{ IPMI_LANP_DEST_TYPE, 4, "Destination Type" },
|
||||
{ IPMI_LANP_DEST_ADDR, 13, "Destination Addresses" },
|
||||
{ IPMI_LANP_OEM_ALERT_STRING, 28, "OEM Alert String" },
|
||||
{ IPMI_LANP_VLAN_ID, 2, "802.1q VLAN ID" }, /* 20 */
|
||||
{ IPMI_LANP_VLAN_PRIORITY, 1, "802.1q VLAN Priority" },
|
||||
{ IPMI_LANP_RMCP_CIPHER_SUPPORT,1, "RMCP+ Cipher Suite Count" },
|
||||
{ IPMI_LANP_RMCP_CIPHERS, 16, "RMCP+ Cipher Suites" },
|
||||
{ IPMI_LANP_RMCP_PRIV_LEVELS, 9, "Cipher Suite Priv Max" },
|
||||
{ IPMI_LANP_OEM_ALERT_STRING, 28, "OEM Alert String" }, /* 25 */
|
||||
{ IPMI_LANP_ALERT_RETRY, 1, "Alert Retry Algorithm" },
|
||||
{ IPMI_LANP_UTC_OFFSET, 3, "UTC Offset" },
|
||||
{ IPMI_LANP_DHCP_SERVER_IP, 4, "DHCP Server IP" },
|
||||
{ IPMI_LANP_DHCP_SERVER_MAC, 6, "DHDP Server MAC" },
|
||||
{ IPMI_LANP_DHCP_ENABLE, 1, "DHCP Enable" },
|
||||
{ IPMI_LANP_DHCP_ENABLE, 1, "DHCP Enable" }, /* 30 */
|
||||
{ IPMI_LANP_CHAN_ACCESS_MODE, 2, "Channel Access Mode" },
|
||||
{ -1 }
|
||||
};
|
||||
|
46
ipmitool/include/ipmitool/ipmi_main.h
Normal file
46
ipmitool/include/ipmitool/ipmi_main.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef IPMI_MAIN_H
|
||||
#define IPMI_MAIN_H
|
||||
|
||||
#include <ipmitool/ipmi_intf.h>
|
||||
|
||||
int ipmi_main(int argc, char ** argv, struct ipmi_cmd * cmdlist, struct ipmi_intf_support * intflist);
|
||||
void ipmi_cmd_print(struct ipmi_cmd * cmdlist);
|
||||
int ipmi_cmd_run(struct ipmi_intf * intf, char * name, int argc, char ** argv);
|
||||
|
||||
#endif /* IPMI_MAIN_H */
|
@ -45,6 +45,7 @@
|
||||
#define BMC_GET_SELF_TEST 0x04
|
||||
#define BMC_SET_GLOBAL_ENABLES 0x2e
|
||||
#define BMC_GET_GLOBAL_ENABLES 0x2f
|
||||
#define BMC_GET_GUID 0x37
|
||||
|
||||
int ipmi_mc_main(struct ipmi_intf *, int, char **);
|
||||
|
||||
@ -83,4 +84,24 @@ struct ipm_devid_rsp {
|
||||
|
||||
#define IPM_DEV_ADTL_SUPPORT_BITS (8)
|
||||
|
||||
#endif /*IPMI_MC_H*/
|
||||
struct ipm_selftest_rsp {
|
||||
unsigned char code;
|
||||
unsigned char test;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define IPM_SFT_CODE_OK 0x55
|
||||
#define IPM_SFT_CODE_NOT_IMPLEMENTED 0x56
|
||||
#define IPM_SFT_CODE_DEV_CORRUPTED 0x57
|
||||
#define IPM_SFT_CODE_FATAL_ERROR 0x58
|
||||
#define IPM_SFT_CODE_RESERVED 0xff
|
||||
|
||||
#define IPM_SELFTEST_SEL_ERROR 0x80
|
||||
#define IPM_SELFTEST_SDR_ERROR 0x40
|
||||
#define IPM_SELFTEST_FRU_ERROR 0x20
|
||||
#define IPM_SELFTEST_IPMB_ERROR 0x10
|
||||
#define IPM_SELFTEST_SDRR_EMPTY 0x08
|
||||
#define IPM_SELFTEST_INTERNAL_USE 0x04
|
||||
#define IPM_SELFTEST_FW_BOOTBLOCK 0x02
|
||||
#define IPM_SELFTEST_FW_CORRUPTED 0x01
|
||||
|
||||
#endif /*IPMI_MC_H */
|
||||
|
@ -47,6 +47,13 @@ struct pef_capabilities { /* "get pef capabilities" response */
|
||||
uint8_t tblsize;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
P_TRUE,
|
||||
P_SUPP,
|
||||
P_ACTV,
|
||||
P_ABLE,
|
||||
} flg_e;
|
||||
|
||||
struct pef_table_entry {
|
||||
#define PEF_CONFIG_ENABLED 0x80
|
||||
#define PEF_CONFIG_PRECONFIGURED 0x40
|
||||
@ -769,7 +776,7 @@ BIT_DESC_MAP_LIST,
|
||||
#define IPMI_CMD_SERIAL_GET_CONFIG 0x11
|
||||
|
||||
const char * ipmi_pef_bit_desc(struct bit_desc_map * map, uint32_t val);
|
||||
void ipmi_pef_print_flags(struct bit_desc_map * map, uint32_t type, uint32_t val);
|
||||
void ipmi_pef_print_flags(struct bit_desc_map * map, flg_e type, uint32_t val);
|
||||
void ipmi_pef_print_dec(const char * text, uint32_t val);
|
||||
void ipmi_pef_print_hex(const char * text, uint32_t val);
|
||||
void ipmi_pef_print_1xd(const char * text, uint32_t val);
|
||||
|
75
ipmitool/include/ipmitool/ipmi_picmg.h
Normal file
75
ipmitool/include/ipmitool/ipmi_picmg.h
Normal file
@ -0,0 +1,75 @@
|
||||
|
||||
/*
|
||||
(C) Kontron
|
||||
*/
|
||||
|
||||
#ifndef _IPMI_PICMG_H_
|
||||
#define _IPMI_PICMG_H_
|
||||
|
||||
#include <ipmitool/ipmi.h>
|
||||
|
||||
/* PICMG commands */
|
||||
#define PICMG_GET_PICMG_PROPERTIES_CMD 0x00
|
||||
#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_GET_FRU_LED_PROPERTIES_CMD 0x05
|
||||
#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_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_SET_FAN_LEVEL_CMD 0x15
|
||||
#define PICMG_GET_FAN_LEVEL_CMD 0x16
|
||||
#define PICMG_BUSED_RESOURCE_CMD 0x17
|
||||
|
||||
/* Site Types */
|
||||
#define PICMG_ATCA_BOARD 0x00
|
||||
#define PICMG_POWER_ENTRY 0x01
|
||||
#define PICMG_SHELF_FRU 0x02
|
||||
#define PICMG_DEDICATED_SHMC 0x03
|
||||
#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
|
||||
|
||||
|
||||
|
||||
struct picmg_set_fru_activation_cmd {
|
||||
unsigned char picmg_id; /* always 0*/
|
||||
unsigned char fru_id; /* threshold setting mask */
|
||||
unsigned char fru_state; /* fru activation/deactivation */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
|
||||
/* the LED color capabilities */
|
||||
static unsigned char* led_color_str[] = {
|
||||
"reserved",
|
||||
"BLUE",
|
||||
"RED",
|
||||
"GREEN",
|
||||
"AMBER",
|
||||
"ORANGE",
|
||||
"WHITE",
|
||||
"reserved"
|
||||
};
|
||||
|
||||
|
||||
|
||||
int ipmi_picmg_main (struct ipmi_intf * intf, int argc, char ** argv);
|
||||
|
||||
#endif
|
@ -40,5 +40,7 @@
|
||||
#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);
|
||||
int ipmi_rawi2c_main(struct ipmi_intf * intf, int argc, char ** argv);
|
||||
|
||||
#endif /* IPMI_RAW_H */
|
||||
|
@ -48,27 +48,41 @@
|
||||
#include <ipmitool/ipmi_entity.h>
|
||||
|
||||
int ipmi_sdr_main(struct ipmi_intf *, int, char **);
|
||||
int32_t utos(uint32_t val, int bits);
|
||||
|
||||
#define tos32(val, bits) ((val & ((1<<((bits)-1)))) ? (-((val) & (1<<((bits)-1))) | (val)) : (val))
|
||||
|
||||
#if WORDS_BIGENDIAN
|
||||
# define __TO_TOL(mtol) (uint16_t)(mtol & 0x3f)
|
||||
# define __TO_M(mtol) (int16_t)(utos((((mtol & 0xff00) >> 8) | ((mtol & 0xc0) << 2)), 10))
|
||||
# define __TO_B(bacc) (int32_t)(utos((((bacc & 0xff000000) >> 24) | ((bacc & 0xc00000) >> 14)), 10))
|
||||
# define __TO_M(mtol) (int16_t)(tos32((((mtol & 0xff00) >> 8) | ((mtol & 0xc0) << 2)), 10))
|
||||
# define __TO_B(bacc) (int32_t)(tos32((((bacc & 0xff000000) >> 24) | ((bacc & 0xc00000) >> 14)), 10))
|
||||
# define __TO_ACC(bacc) (uint32_t)(((bacc & 0x3f0000) >> 16) | ((bacc & 0xf000) >> 6))
|
||||
# define __TO_ACC_EXP(bacc) (uint32_t)((bacc & 0xc00) >> 10)
|
||||
# define __TO_R_EXP(bacc) (int32_t)(utos(((bacc & 0xf0) >> 4), 4))
|
||||
# define __TO_B_EXP(bacc) (int32_t)(utos((bacc & 0xf), 4))
|
||||
# define __TO_R_EXP(bacc) (int32_t)(tos32(((bacc & 0xf0) >> 4), 4))
|
||||
# define __TO_B_EXP(bacc) (int32_t)(tos32((bacc & 0xf), 4))
|
||||
#else
|
||||
# define __TO_TOL(mtol) (uint16_t)(BSWAP_16(mtol) & 0x3f)
|
||||
# define __TO_M(mtol) (int16_t)(utos((((BSWAP_16(mtol) & 0xff00) >> 8) | ((BSWAP_16(mtol) & 0xc0) << 2)), 10))
|
||||
# define __TO_B(bacc) (int32_t)(utos((((BSWAP_32(bacc) & 0xff000000) >> 24) | \
|
||||
# define __TO_M(mtol) (int16_t)(tos32((((BSWAP_16(mtol) & 0xff00) >> 8) | ((BSWAP_16(mtol) & 0xc0) << 2)), 10))
|
||||
# define __TO_B(bacc) (int32_t)(tos32((((BSWAP_32(bacc) & 0xff000000) >> 24) | \
|
||||
((BSWAP_32(bacc) & 0xc00000) >> 14)), 10))
|
||||
# define __TO_ACC(bacc) (uint32_t)(((BSWAP_32(bacc) & 0x3f0000) >> 16) | ((BSWAP_32(bacc) & 0xf000) >> 6))
|
||||
# define __TO_ACC_EXP(bacc) (uint32_t)((BSWAP_32(bacc) & 0xc00) >> 10)
|
||||
# define __TO_R_EXP(bacc) (int32_t)(utos(((BSWAP_32(bacc) & 0xf0) >> 4), 4))
|
||||
# define __TO_B_EXP(bacc) (int32_t)(utos((BSWAP_32(bacc) & 0xf), 4))
|
||||
# define __TO_R_EXP(bacc) (int32_t)(tos32(((BSWAP_32(bacc) & 0xf0) >> 4), 4))
|
||||
# define __TO_B_EXP(bacc) (int32_t)(tos32((BSWAP_32(bacc) & 0xf), 4))
|
||||
#endif
|
||||
|
||||
enum {
|
||||
ANALOG_SENSOR,
|
||||
DISCRETE_SENSOR,
|
||||
};
|
||||
|
||||
#define READING_UNAVAILABLE 0x20
|
||||
#define SCANNING_DISABLED 0x40
|
||||
#define EVENT_MSG_DISABLED 0x80
|
||||
|
||||
#define IS_READING_UNAVAILABLE(val) ((val) & READING_UNAVAILABLE)
|
||||
#define IS_SCANNING_DISABLED(val) (!((val) & SCANNING_DISABLED))
|
||||
#define IS_EVENT_MSG_DISABLED(val) (!((val) & EVENT_MSG_DISABLED))
|
||||
|
||||
#define GET_SDR_REPO_INFO 0x20
|
||||
#define GET_SDR_ALLOC_INFO 0x21
|
||||
|
||||
@ -79,6 +93,22 @@ int32_t utos(uint32_t val, int bits);
|
||||
#define SDR_SENSOR_STAT_HI_CR (1<<4)
|
||||
#define SDR_SENSOR_STAT_HI_NR (1<<5)
|
||||
|
||||
#define GET_DEVICE_SDR_INFO 0x20
|
||||
#define GET_DEVICE_SDR 0x21
|
||||
#define GET_SENSOR_FACTORS 0x23
|
||||
#define GET_SENSOR_FACTORS 0x23
|
||||
#define SET_SENSOR_HYSTERESIS 0x24
|
||||
#define GET_SENSOR_HYSTERESIS 0x25
|
||||
#define SET_SENSOR_THRESHOLDS 0x26
|
||||
#define GET_SENSOR_THRESHOLDS 0x27
|
||||
#define SET_SENSOR_EVENT_ENABLE 0x28
|
||||
#define GET_SENSOR_EVENT_ENABLE 0x29
|
||||
#define GET_SENSOR_EVENT_STATUS 0x2b
|
||||
#define GET_SENSOR_READING 0x2d
|
||||
#define GET_SENSOR_TYPE 0x2f
|
||||
#define GET_SENSOR_READING 0x2d
|
||||
#define GET_SENSOR_TYPE 0x2f
|
||||
|
||||
struct sdr_repo_info_rs {
|
||||
uint8_t version; /* SDR version (51h) */
|
||||
uint16_t count; /* number of records */
|
||||
@ -88,6 +118,13 @@ struct sdr_repo_info_rs {
|
||||
uint8_t op_support; /* supported operations */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* builtin (device) sdrs support */
|
||||
struct sdr_device_info_rs {
|
||||
unsigned char count; /* number of records */
|
||||
unsigned char flags; /* flags */
|
||||
unsigned char popChangeInd[3]; /* free space in SDR */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define GET_SDR_RESERVE_REPO 0x22
|
||||
struct sdr_reserve_repo_rs {
|
||||
uint16_t reserve_id; /* reservation ID */
|
||||
@ -121,17 +158,137 @@ struct sdr_get_rs {
|
||||
uint8_t length; /* remaining record bytes */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct sdr_record_mask {
|
||||
union {
|
||||
struct {
|
||||
uint16_t assert_event; /* assertion event mask */
|
||||
uint16_t deassert_event; /* de-assertion event mask */
|
||||
uint16_t read; /* discrete reaading mask */
|
||||
} discrete;
|
||||
struct {
|
||||
#if WORDS_BIGENDIAN
|
||||
uint16_t reserved:1;
|
||||
uint16_t status_lnr:1;
|
||||
uint16_t status_lcr:1;
|
||||
uint16_t status_lnc:1;
|
||||
uint16_t assert_unr_high:1;
|
||||
uint16_t assert_unr_low:1;
|
||||
uint16_t assert_ucr_high:1;
|
||||
uint16_t assert_ucr_low:1;
|
||||
uint16_t assert_unc_high:1;
|
||||
uint16_t assert_unc_low:1;
|
||||
uint16_t assert_lnr_high:1;
|
||||
uint16_t assert_lnr_low:1;
|
||||
uint16_t assert_lcr_high:1;
|
||||
uint16_t assert_lcr_low:1;
|
||||
uint16_t assert_lnc_high:1;
|
||||
uint16_t assert_lnc_low:1;
|
||||
#else
|
||||
uint16_t assert_lnc_low:1;
|
||||
uint16_t assert_lnc_high:1;
|
||||
uint16_t assert_lcr_low:1;
|
||||
uint16_t assert_lcr_high:1;
|
||||
uint16_t assert_lnr_low:1;
|
||||
uint16_t assert_lnr_high:1;
|
||||
uint16_t assert_unc_low:1;
|
||||
uint16_t assert_unc_high:1;
|
||||
uint16_t assert_ucr_low:1;
|
||||
uint16_t assert_ucr_high:1;
|
||||
uint16_t assert_unr_low:1;
|
||||
uint16_t assert_unr_high:1;
|
||||
uint16_t status_lnc:1;
|
||||
uint16_t status_lcr:1;
|
||||
uint16_t status_lnr:1;
|
||||
uint16_t reserved:1;
|
||||
#endif
|
||||
#if WORDS_BIGENDIAN
|
||||
uint16_t reserved_2:1;
|
||||
uint16_t status_unr:1;
|
||||
uint16_t status_ucr:1;
|
||||
uint16_t status_unc:1;
|
||||
uint16_t deassert_unr_high:1;
|
||||
uint16_t deassert_unr_low:1;
|
||||
uint16_t deassert_ucr_high:1;
|
||||
uint16_t deassert_ucr_low:1;
|
||||
uint16_t deassert_unc_high:1;
|
||||
uint16_t deassert_unc_low:1;
|
||||
uint16_t deassert_lnr_high:1;
|
||||
uint16_t deassert_lnr_low:1;
|
||||
uint16_t deassert_lcr_high:1;
|
||||
uint16_t deassert_lcr_low:1;
|
||||
uint16_t deassert_lnc_high:1;
|
||||
uint16_t deassert_lnc_low:1;
|
||||
#else
|
||||
uint16_t deassert_lnc_low:1;
|
||||
uint16_t deassert_lnc_high:1;
|
||||
uint16_t deassert_lcr_low:1;
|
||||
uint16_t deassert_lcr_high:1;
|
||||
uint16_t deassert_lnr_low:1;
|
||||
uint16_t deassert_lnr_high:1;
|
||||
uint16_t deassert_unc_low:1;
|
||||
uint16_t deassert_unc_high:1;
|
||||
uint16_t deassert_ucr_low:1;
|
||||
uint16_t deassert_ucr_high:1;
|
||||
uint16_t deassert_unr_low:1;
|
||||
uint16_t deassert_unr_high:1;
|
||||
uint16_t status_unc:1;
|
||||
uint16_t status_ucr:1;
|
||||
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;
|
||||
#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;
|
||||
#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;
|
||||
#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;
|
||||
#endif
|
||||
} read;
|
||||
} threshold;
|
||||
} type;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct sdr_record_compact_sensor {
|
||||
struct {
|
||||
uint8_t owner_id;
|
||||
#if WORDS_BIGENDIAN
|
||||
uint8_t channel : 4; /* channel number */
|
||||
uint8_t __reserved : 2;
|
||||
uint8_t lun : 2; /* sensor owner lun */
|
||||
uint8_t channel:4; /* channel number */
|
||||
uint8_t __reserved:2;
|
||||
uint8_t lun:2; /* sensor owner lun */
|
||||
#else
|
||||
uint8_t lun : 2; /* sensor owner lun */
|
||||
uint8_t __reserved : 2;
|
||||
uint8_t channel : 4; /* channel number */
|
||||
uint8_t lun:2; /* sensor owner lun */
|
||||
uint8_t __reserved:2;
|
||||
uint8_t channel:4; /* channel number */
|
||||
#endif
|
||||
uint8_t sensor_num; /* unique sensor number */
|
||||
} keys;
|
||||
@ -141,38 +298,38 @@ struct sdr_record_compact_sensor {
|
||||
struct {
|
||||
struct {
|
||||
#if WORDS_BIGENDIAN
|
||||
uint8_t __reserved : 1;
|
||||
uint8_t scanning : 1;
|
||||
uint8_t events : 1;
|
||||
uint8_t thresholds : 1;
|
||||
uint8_t hysteresis : 1;
|
||||
uint8_t type : 1;
|
||||
uint8_t event_gen : 1;
|
||||
uint8_t sensor_scan : 1;
|
||||
uint8_t __reserved:1;
|
||||
uint8_t scanning:1;
|
||||
uint8_t events:1;
|
||||
uint8_t thresholds:1;
|
||||
uint8_t hysteresis:1;
|
||||
uint8_t type:1;
|
||||
uint8_t event_gen:1;
|
||||
uint8_t sensor_scan:1;
|
||||
#else
|
||||
uint8_t sensor_scan : 1;
|
||||
uint8_t event_gen : 1;
|
||||
uint8_t type : 1;
|
||||
uint8_t hysteresis : 1;
|
||||
uint8_t thresholds : 1;
|
||||
uint8_t events : 1;
|
||||
uint8_t scanning : 1;
|
||||
uint8_t __reserved : 1;
|
||||
uint8_t sensor_scan:1;
|
||||
uint8_t event_gen:1;
|
||||
uint8_t type:1;
|
||||
uint8_t hysteresis:1;
|
||||
uint8_t thresholds:1;
|
||||
uint8_t events:1;
|
||||
uint8_t scanning:1;
|
||||
uint8_t __reserved:1;
|
||||
#endif
|
||||
} init;
|
||||
struct {
|
||||
#if WORDS_BIGENDIAN
|
||||
uint8_t ignore : 1;
|
||||
uint8_t rearm : 1;
|
||||
uint8_t hysteresis : 2;
|
||||
uint8_t threshold : 2;
|
||||
uint8_t event_msg : 2;
|
||||
uint8_t ignore:1;
|
||||
uint8_t rearm:1;
|
||||
uint8_t hysteresis:2;
|
||||
uint8_t threshold:2;
|
||||
uint8_t event_msg:2;
|
||||
#else
|
||||
uint8_t event_msg : 2;
|
||||
uint8_t threshold : 2;
|
||||
uint8_t hysteresis : 2;
|
||||
uint8_t rearm : 1;
|
||||
uint8_t ignore : 1;
|
||||
uint8_t event_msg:2;
|
||||
uint8_t threshold:2;
|
||||
uint8_t hysteresis:2;
|
||||
uint8_t rearm:1;
|
||||
uint8_t ignore:1;
|
||||
#endif
|
||||
} capabilities;
|
||||
uint8_t type; /* sensor type */
|
||||
@ -180,31 +337,19 @@ struct sdr_record_compact_sensor {
|
||||
|
||||
uint8_t event_type; /* event/reading type code */
|
||||
|
||||
union {
|
||||
struct {
|
||||
uint16_t assert_event; /* assertion event mask */
|
||||
uint16_t deassert_event; /* de-assertion event mask */
|
||||
uint16_t read; /* discrete reaading mask */
|
||||
} discrete;
|
||||
struct {
|
||||
uint16_t lower; /* lower threshold reading mask */
|
||||
uint16_t upper; /* upper threshold reading mask */
|
||||
uint8_t set; /* settable threshold mask */
|
||||
uint8_t read; /* readable threshold mask */
|
||||
} threshold;
|
||||
} mask;
|
||||
struct sdr_record_mask mask;
|
||||
|
||||
struct {
|
||||
#if WORDS_BIGENDIAN
|
||||
uint8_t analog : 2;
|
||||
uint8_t rate : 3;
|
||||
uint8_t modifier : 2;
|
||||
uint8_t pct : 1;
|
||||
uint8_t analog:2;
|
||||
uint8_t rate:3;
|
||||
uint8_t modifier:2;
|
||||
uint8_t pct:1;
|
||||
#else
|
||||
uint8_t pct : 1;
|
||||
uint8_t modifier : 2;
|
||||
uint8_t rate : 3;
|
||||
uint8_t analog : 2;
|
||||
uint8_t pct:1;
|
||||
uint8_t modifier:2;
|
||||
uint8_t rate:3;
|
||||
uint8_t analog:2;
|
||||
#endif
|
||||
struct {
|
||||
uint8_t base;
|
||||
@ -214,20 +359,20 @@ struct sdr_record_compact_sensor {
|
||||
|
||||
struct {
|
||||
#if WORDS_BIGENDIAN
|
||||
uint8_t __reserved : 2;
|
||||
uint8_t mod_type : 2;
|
||||
uint8_t count : 4;
|
||||
uint8_t __reserved:2;
|
||||
uint8_t mod_type:2;
|
||||
uint8_t count:4;
|
||||
#else
|
||||
uint8_t count : 4;
|
||||
uint8_t mod_type : 2;
|
||||
uint8_t __reserved : 2;
|
||||
uint8_t count:4;
|
||||
uint8_t mod_type:2;
|
||||
uint8_t __reserved:2;
|
||||
#endif
|
||||
#if WORDS_BIGENDIAN
|
||||
uint8_t entity_inst : 1;
|
||||
uint8_t mod_offset : 7;
|
||||
uint8_t entity_inst:1;
|
||||
uint8_t mod_offset:7;
|
||||
#else
|
||||
uint8_t mod_offset : 7;
|
||||
uint8_t entity_inst : 1;
|
||||
uint8_t mod_offset:7;
|
||||
uint8_t entity_inst:1;
|
||||
#endif
|
||||
} share;
|
||||
|
||||
@ -248,13 +393,13 @@ struct sdr_record_eventonly_sensor {
|
||||
struct {
|
||||
uint8_t owner_id;
|
||||
#if WORDS_BIGENDIAN
|
||||
uint8_t channel : 4; /* channel number */
|
||||
uint8_t fru_owner : 2; /* fru device owner lun */
|
||||
uint8_t lun : 2; /* sensor owner lun */
|
||||
uint8_t channel:4; /* channel number */
|
||||
uint8_t fru_owner:2; /* fru device owner lun */
|
||||
uint8_t lun:2; /* sensor owner lun */
|
||||
#else
|
||||
uint8_t lun : 2; /* sensor owner lun */
|
||||
uint8_t fru_owner : 2; /* fru device owner lun */
|
||||
uint8_t channel : 4; /* channel number */
|
||||
uint8_t lun:2; /* sensor owner lun */
|
||||
uint8_t fru_owner:2; /* fru device owner lun */
|
||||
uint8_t channel:4; /* channel number */
|
||||
#endif
|
||||
uint8_t sensor_num; /* unique sensor number */
|
||||
} keys;
|
||||
@ -266,20 +411,20 @@ struct sdr_record_eventonly_sensor {
|
||||
|
||||
struct {
|
||||
#if WORDS_BIGENDIAN
|
||||
uint8_t __reserved : 2;
|
||||
uint8_t mod_type : 2;
|
||||
uint8_t count : 4;
|
||||
uint8_t __reserved:2;
|
||||
uint8_t mod_type:2;
|
||||
uint8_t count:4;
|
||||
#else
|
||||
uint8_t count : 4;
|
||||
uint8_t mod_type : 2;
|
||||
uint8_t __reserved : 2;
|
||||
uint8_t count:4;
|
||||
uint8_t mod_type:2;
|
||||
uint8_t __reserved:2;
|
||||
#endif
|
||||
#if WORDS_BIGENDIAN
|
||||
uint8_t entity_inst : 1;
|
||||
uint8_t mod_offset : 7;
|
||||
uint8_t entity_inst:1;
|
||||
uint8_t mod_offset:7;
|
||||
#else
|
||||
uint8_t mod_offset : 7;
|
||||
uint8_t entity_inst : 1;
|
||||
uint8_t mod_offset:7;
|
||||
uint8_t entity_inst:1;
|
||||
#endif
|
||||
} share;
|
||||
|
||||
@ -294,13 +439,13 @@ struct sdr_record_full_sensor {
|
||||
struct {
|
||||
uint8_t owner_id;
|
||||
#if WORDS_BIGENDIAN
|
||||
uint8_t channel : 4; /* channel number */
|
||||
uint8_t __reserved : 2;
|
||||
uint8_t lun : 2; /* sensor owner lun */
|
||||
uint8_t channel:4; /* channel number */
|
||||
uint8_t __reserved:2;
|
||||
uint8_t lun:2; /* sensor owner lun */
|
||||
#else
|
||||
uint8_t lun : 2; /* sensor owner lun */
|
||||
uint8_t __reserved : 2;
|
||||
uint8_t channel : 4; /* channel number */
|
||||
uint8_t lun:2; /* sensor owner lun */
|
||||
uint8_t __reserved:2;
|
||||
uint8_t channel:4; /* channel number */
|
||||
#endif
|
||||
uint8_t sensor_num; /* unique sensor number */
|
||||
} keys;
|
||||
@ -310,38 +455,38 @@ struct sdr_record_full_sensor {
|
||||
struct {
|
||||
struct {
|
||||
#if WORDS_BIGENDIAN
|
||||
uint8_t __reserved : 1;
|
||||
uint8_t scanning : 1;
|
||||
uint8_t events : 1;
|
||||
uint8_t thresholds : 1;
|
||||
uint8_t hysteresis : 1;
|
||||
uint8_t type : 1;
|
||||
uint8_t event_gen : 1;
|
||||
uint8_t sensor_scan : 1;
|
||||
uint8_t __reserved:1;
|
||||
uint8_t scanning:1;
|
||||
uint8_t events:1;
|
||||
uint8_t thresholds:1;
|
||||
uint8_t hysteresis:1;
|
||||
uint8_t type:1;
|
||||
uint8_t event_gen:1;
|
||||
uint8_t sensor_scan:1;
|
||||
#else
|
||||
uint8_t sensor_scan : 1;
|
||||
uint8_t event_gen : 1;
|
||||
uint8_t type : 1;
|
||||
uint8_t hysteresis : 1;
|
||||
uint8_t thresholds : 1;
|
||||
uint8_t events : 1;
|
||||
uint8_t scanning : 1;
|
||||
uint8_t __reserved : 1;
|
||||
uint8_t sensor_scan:1;
|
||||
uint8_t event_gen:1;
|
||||
uint8_t type:1;
|
||||
uint8_t hysteresis:1;
|
||||
uint8_t thresholds:1;
|
||||
uint8_t events:1;
|
||||
uint8_t scanning:1;
|
||||
uint8_t __reserved:1;
|
||||
#endif
|
||||
} init;
|
||||
struct {
|
||||
#if WORDS_BIGENDIAN
|
||||
uint8_t ignore : 1;
|
||||
uint8_t rearm : 1;
|
||||
uint8_t hysteresis : 2;
|
||||
uint8_t threshold : 2;
|
||||
uint8_t event_msg : 2;
|
||||
uint8_t ignore:1;
|
||||
uint8_t rearm:1;
|
||||
uint8_t hysteresis:2;
|
||||
uint8_t threshold:2;
|
||||
uint8_t event_msg:2;
|
||||
#else
|
||||
uint8_t event_msg : 2;
|
||||
uint8_t threshold : 2;
|
||||
uint8_t hysteresis : 2;
|
||||
uint8_t rearm : 1;
|
||||
uint8_t ignore : 1;
|
||||
uint8_t event_msg:2;
|
||||
uint8_t threshold:2;
|
||||
uint8_t hysteresis:2;
|
||||
uint8_t rearm:1;
|
||||
uint8_t ignore:1;
|
||||
#endif
|
||||
} capabilities;
|
||||
uint8_t type;
|
||||
@ -349,31 +494,19 @@ struct sdr_record_full_sensor {
|
||||
|
||||
uint8_t event_type; /* event/reading type code */
|
||||
|
||||
union {
|
||||
struct {
|
||||
uint16_t assert_event; /* assertion event mask */
|
||||
uint16_t deassert_event; /* de-assertion event mask */
|
||||
uint16_t read; /* discrete reaading mask */
|
||||
} discrete;
|
||||
struct {
|
||||
uint16_t lower; /* lower threshold reading mask */
|
||||
uint16_t upper; /* upper threshold reading mask */
|
||||
uint8_t set; /* settable threshold mask */
|
||||
uint8_t read; /* readable threshold mask */
|
||||
} threshold;
|
||||
} mask;
|
||||
struct sdr_record_mask mask;
|
||||
|
||||
struct {
|
||||
#if WORDS_BIGENDIAN
|
||||
uint8_t analog : 2;
|
||||
uint8_t rate : 3;
|
||||
uint8_t modifier : 2;
|
||||
uint8_t pct : 1;
|
||||
uint8_t analog:2;
|
||||
uint8_t rate:3;
|
||||
uint8_t modifier:2;
|
||||
uint8_t pct:1;
|
||||
#else
|
||||
uint8_t pct : 1;
|
||||
uint8_t modifier : 2;
|
||||
uint8_t rate : 3;
|
||||
uint8_t analog : 2;
|
||||
uint8_t pct:1;
|
||||
uint8_t modifier:2;
|
||||
uint8_t rate:3;
|
||||
uint8_t analog:2;
|
||||
#endif
|
||||
struct {
|
||||
uint8_t base;
|
||||
@ -381,21 +514,35 @@ struct sdr_record_full_sensor {
|
||||
} type;
|
||||
} unit;
|
||||
|
||||
#define SDR_SENSOR_L_LINEAR 0x00
|
||||
#define SDR_SENSOR_L_LN 0x01
|
||||
#define SDR_SENSOR_L_LOG10 0x02
|
||||
#define SDR_SENSOR_L_LOG2 0x03
|
||||
#define SDR_SENSOR_L_E 0x04
|
||||
#define SDR_SENSOR_L_EXP10 0x05
|
||||
#define SDR_SENSOR_L_EXP2 0x06
|
||||
#define SDR_SENSOR_L_1_X 0x07
|
||||
#define SDR_SENSOR_L_SQR 0x08
|
||||
#define SDR_SENSOR_L_CUBE 0x09
|
||||
#define SDR_SENSOR_L_SQRT 0x0a
|
||||
#define SDR_SENSOR_L_CUBERT 0x0b
|
||||
#define SDR_SENSOR_L_NONLINEAR 0x70
|
||||
|
||||
uint8_t linearization; /* 70h=non linear, 71h-7Fh=non linear, OEM */
|
||||
uint16_t mtol; /* M, tolerance */
|
||||
uint32_t bacc; /* accuracy, B, Bexp, Rexp */
|
||||
|
||||
struct {
|
||||
#if WORDS_BIGENDIAN
|
||||
uint8_t __reserved : 5;
|
||||
uint8_t normal_min : 1; /* normal min field specified */
|
||||
uint8_t normal_max : 1; /* normal max field specified */
|
||||
uint8_t nominal_read : 1; /* nominal reading field specified */
|
||||
uint8_t __reserved:5;
|
||||
uint8_t normal_min:1; /* normal min field specified */
|
||||
uint8_t normal_max:1; /* normal max field specified */
|
||||
uint8_t nominal_read:1; /* nominal reading field specified */
|
||||
#else
|
||||
uint8_t nominal_read : 1; /* nominal reading field specified */
|
||||
uint8_t normal_max : 1; /* normal max field specified */
|
||||
uint8_t normal_min : 1; /* normal min field specified */
|
||||
uint8_t __reserved : 5;
|
||||
uint8_t nominal_read:1; /* nominal reading field specified */
|
||||
uint8_t normal_max:1; /* normal max field specified */
|
||||
uint8_t normal_min:1; /* normal min field specified */
|
||||
uint8_t __reserved:5;
|
||||
#endif
|
||||
} analog_flag;
|
||||
|
||||
@ -430,20 +577,20 @@ struct sdr_record_full_sensor {
|
||||
struct sdr_record_mc_locator {
|
||||
uint8_t dev_slave_addr;
|
||||
#if WORDS_BIGENDIAN
|
||||
uint8_t __reserved2 : 4;
|
||||
uint8_t channel_num : 4;
|
||||
uint8_t __reserved2:4;
|
||||
uint8_t channel_num:4;
|
||||
#else
|
||||
uint8_t channel_num : 4;
|
||||
uint8_t __reserved2 : 4;
|
||||
uint8_t channel_num:4;
|
||||
uint8_t __reserved2:4;
|
||||
#endif
|
||||
#if WORDS_BIGENDIAN
|
||||
uint8_t pwr_state_notif : 3;
|
||||
uint8_t __reserved3 : 1;
|
||||
uint8_t global_init : 4;
|
||||
uint8_t pwr_state_notif:3;
|
||||
uint8_t __reserved3:1;
|
||||
uint8_t global_init:4;
|
||||
#else
|
||||
uint8_t global_init : 4;
|
||||
uint8_t __reserved3 : 1;
|
||||
uint8_t pwr_state_notif : 3;
|
||||
uint8_t global_init:4;
|
||||
uint8_t __reserved3:1;
|
||||
uint8_t pwr_state_notif:3;
|
||||
#endif
|
||||
uint8_t dev_support;
|
||||
uint8_t __reserved4[3];
|
||||
@ -457,22 +604,22 @@ struct sdr_record_fru_locator {
|
||||
uint8_t dev_slave_addr;
|
||||
uint8_t device_id;
|
||||
#if WORDS_BIGENDIAN
|
||||
uint8_t bus : 3;
|
||||
uint8_t lun : 2;
|
||||
uint8_t __reserved2 : 2;
|
||||
uint8_t logical : 1;
|
||||
uint8_t logical:1;
|
||||
uint8_t __reserved2:2;
|
||||
uint8_t lun:2;
|
||||
uint8_t bus:3;
|
||||
#else
|
||||
uint8_t logical : 1;
|
||||
uint8_t __reserved2 : 2;
|
||||
uint8_t lun : 2;
|
||||
uint8_t bus : 3;
|
||||
uint8_t bus:3;
|
||||
uint8_t lun:2;
|
||||
uint8_t __reserved2:2;
|
||||
uint8_t logical:1;
|
||||
#endif
|
||||
#if WORDS_BIGENDIAN
|
||||
uint8_t __reserved3 : 4;
|
||||
uint8_t channel_num : 4;
|
||||
uint8_t channel_num:4;
|
||||
uint8_t __reserved3:4;
|
||||
#else
|
||||
uint8_t channel_num : 4;
|
||||
uint8_t __reserved3 : 4;
|
||||
uint8_t __reserved3:4;
|
||||
uint8_t channel_num:4;
|
||||
#endif
|
||||
uint8_t __reserved4;
|
||||
uint8_t dev_type;
|
||||
@ -483,8 +630,61 @@ struct sdr_record_fru_locator {
|
||||
uint8_t id_string[16];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct sdr_record_generic_locator {
|
||||
uint8_t dev_access_addr;
|
||||
uint8_t dev_slave_addr;
|
||||
#if WORDS_BIGENDIAN
|
||||
uint8_t channel_num:3;
|
||||
uint8_t lun:2;
|
||||
uint8_t bus:3;
|
||||
#else
|
||||
uint8_t bus:3;
|
||||
uint8_t lun:2;
|
||||
uint8_t channel_num:3;
|
||||
#endif
|
||||
#if WORDS_BIGENDIAN
|
||||
uint8_t addr_span:3;
|
||||
uint8_t __reserved1:5;
|
||||
#else
|
||||
uint8_t __reserved1:5;
|
||||
uint8_t addr_span:3;
|
||||
#endif
|
||||
uint8_t __reserved2;
|
||||
uint8_t dev_type;
|
||||
uint8_t dev_type_modifier;
|
||||
struct entity_id entity;
|
||||
uint8_t oem;
|
||||
uint8_t id_code;
|
||||
uint8_t id_string[16];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct sdr_record_entity_assoc {
|
||||
struct entity_id entity; /* container entity ID and instance */
|
||||
struct {
|
||||
#if WORDS_BIGENDIAN
|
||||
uint8_t isrange:1;
|
||||
uint8_t islinked:1;
|
||||
uint8_t isaccessable:1;
|
||||
uint8_t __reserved:5;
|
||||
#else
|
||||
uint8_t __reserved:5;
|
||||
uint8_t isaccessable:1;
|
||||
uint8_t islinked:1;
|
||||
uint8_t isrange:1;
|
||||
#endif
|
||||
} flags;
|
||||
uint8_t entity_id_1; /* entity ID 1 | range 1 entity */
|
||||
uint8_t entity_inst_1; /* entity inst 1 | range 1 first instance */
|
||||
uint8_t entity_id_2; /* entity ID 2 | range 1 entity */
|
||||
uint8_t entity_inst_2; /* entity inst 2 | range 1 last instance */
|
||||
uint8_t entity_id_3; /* entity ID 3 | range 2 entity */
|
||||
uint8_t entity_inst_3; /* entity inst 3 | range 2 first instance */
|
||||
uint8_t entity_id_4; /* entity ID 4 | range 2 entity */
|
||||
uint8_t entity_inst_4; /* entity inst 4 | range 2 last instance */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct sdr_record_oem {
|
||||
uint8_t * data;
|
||||
uint8_t *data;
|
||||
int data_len;
|
||||
};
|
||||
|
||||
@ -500,29 +700,25 @@ struct get_sdr_repository_info_rsp {
|
||||
uint8_t most_recent_addition_timestamp[4];
|
||||
uint8_t most_recent_erase_timestamp[4];
|
||||
#if WORDS_BIGENDIAN
|
||||
uint8_t overflow_flag : 1;
|
||||
uint8_t modal_update_support : 2;
|
||||
uint8_t __reserved1 : 1;
|
||||
uint8_t delete_sdr_supported : 1;
|
||||
uint8_t partial_add_sdr_supported : 1;
|
||||
uint8_t reserve_sdr_repository_supported : 1;
|
||||
uint8_t get_sdr_repository_allo_info_supported : 1;
|
||||
uint8_t overflow_flag:1;
|
||||
uint8_t modal_update_support:2;
|
||||
uint8_t __reserved1:1;
|
||||
uint8_t delete_sdr_supported:1;
|
||||
uint8_t partial_add_sdr_supported:1;
|
||||
uint8_t reserve_sdr_repository_supported:1;
|
||||
uint8_t get_sdr_repository_allo_info_supported:1;
|
||||
#else
|
||||
uint8_t get_sdr_repository_allo_info_supported : 1;
|
||||
uint8_t reserve_sdr_repository_supported : 1;
|
||||
uint8_t partial_add_sdr_supported : 1;
|
||||
uint8_t delete_sdr_supported : 1;
|
||||
uint8_t __reserved1 : 1;
|
||||
uint8_t modal_update_support : 2;
|
||||
uint8_t overflow_flag : 1;
|
||||
uint8_t get_sdr_repository_allo_info_supported:1;
|
||||
uint8_t reserve_sdr_repository_supported:1;
|
||||
uint8_t partial_add_sdr_supported:1;
|
||||
uint8_t delete_sdr_supported:1;
|
||||
uint8_t __reserved1:1;
|
||||
uint8_t modal_update_support:2;
|
||||
uint8_t overflow_flag:1;
|
||||
#endif
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
|
||||
|
||||
struct ipmi_sdr_iterator
|
||||
{
|
||||
struct ipmi_sdr_iterator {
|
||||
uint16_t reservation;
|
||||
int total;
|
||||
int next;
|
||||
@ -531,84 +727,132 @@ struct ipmi_sdr_iterator
|
||||
struct sdr_record_list {
|
||||
uint16_t id;
|
||||
uint8_t type;
|
||||
struct sdr_record_list * next;
|
||||
struct sdr_record_list *next;
|
||||
union {
|
||||
struct sdr_record_full_sensor * full;
|
||||
struct sdr_record_compact_sensor * compact;
|
||||
struct sdr_record_eventonly_sensor * eventonly;
|
||||
struct sdr_record_fru_locator * fruloc;
|
||||
struct sdr_record_mc_locator * mcloc;
|
||||
struct sdr_record_oem * oem;
|
||||
struct sdr_record_full_sensor *full;
|
||||
struct sdr_record_compact_sensor *compact;
|
||||
struct sdr_record_eventonly_sensor *eventonly;
|
||||
struct sdr_record_generic_locator *genloc;
|
||||
struct sdr_record_fru_locator *fruloc;
|
||||
struct sdr_record_mc_locator *mcloc;
|
||||
struct sdr_record_entity_assoc *entassoc;
|
||||
struct sdr_record_oem *oem;
|
||||
} record;
|
||||
};
|
||||
|
||||
/* unit description codes (IPMI v1.5 section 37.16) */
|
||||
#define UNIT_MAX 0x90
|
||||
static const char * unit_desc[] __attribute__((unused)) = {
|
||||
"unspecified",
|
||||
static const char *unit_desc[] __attribute__ ((unused)) = {
|
||||
"unspecified",
|
||||
"degrees C", "degrees F", "degrees K",
|
||||
"Volts", "Amps", "Watts", "Joules",
|
||||
"Coulombs", "VA", "Nits",
|
||||
"lumen", "lux", "Candela",
|
||||
"kPa", "PSI", "Newton",
|
||||
"CFM", "RPM", "Hz",
|
||||
"microsecond", "millisecond", "second", "minute", "hour", "day", "week",
|
||||
"mil", "inches", "feet", "cu in", "cu feet", "mm", "cm", "m", "cu cm", "cu m",
|
||||
"liters", "fluid ounce",
|
||||
"radians", "steradians", "revolutions", "cycles", "gravities",
|
||||
"ounce", "pound", "ft-lb", "oz-in",
|
||||
"gauss", "gilberts", "henry", "millihenry",
|
||||
"farad", "microfarad", "ohms", "siemens", "mole", "becquerel",
|
||||
"PPM", "reserved",
|
||||
"Decibels", "DbA", "DbC",
|
||||
"gray", "sievert", "color temp deg K",
|
||||
"bit", "kilobit", "megabit", "gigabit",
|
||||
"byte", "kilobyte", "megabyte", "gigabyte",
|
||||
"word", "dword", "qword", "line",
|
||||
"hit", "miss", "retry", "reset",
|
||||
"overflow", "underrun",
|
||||
"collision", "packets",
|
||||
"messages", "characters",
|
||||
"error", "correctable error", "uncorrectable error",
|
||||
};
|
||||
"microsecond", "millisecond", "second", "minute", "hour",
|
||||
"day", "week", "mil", "inches", "feet", "cu in", "cu feet",
|
||||
"mm", "cm", "m", "cu cm", "cu m", "liters", "fluid ounce",
|
||||
"radians", "steradians", "revolutions", "cycles",
|
||||
"gravities", "ounce", "pound", "ft-lb", "oz-in", "gauss",
|
||||
"gilberts", "henry", "millihenry", "farad", "microfarad",
|
||||
"ohms", "siemens", "mole", "becquerel", "PPM", "reserved",
|
||||
"Decibels", "DbA", "DbC", "gray", "sievert",
|
||||
"color temp deg K", "bit", "kilobit", "megabit", "gigabit",
|
||||
"byte", "kilobyte", "megabyte", "gigabyte", "word", "dword",
|
||||
"qword", "line", "hit", "miss", "retry", "reset",
|
||||
"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
|
||||
static const char * sensor_type_desc[] __attribute__((unused)) = {
|
||||
"reserved",
|
||||
"Temperature", "Voltage", "Current", "Fan", "Physical Security", "Platform Security Violation Attempt",
|
||||
"Processor", "Power Supply", "Power Unit", "Cooling Device", "Other", "Memory", "Drive Slot / Bay",
|
||||
"POST Memory Resize", "System Firmware Progress", "Event Logging Disabled", "Watchdog", "System Event",
|
||||
"Critical Interrupt", "Button", "Module / Board", "Microcontroller / Coprocessor", "Add-in Card",
|
||||
"Chassis", "Chip Set", "Other FRU", "Cable / Interconnect", "Terminator", "System Boot Initiated",
|
||||
"Boot Error", "OS Boot", "OS Critical Stop", "Slot / Connector", "System ACPI Power State", "Watchdog",
|
||||
"Platform Alert", "Entity Presence", "Monitor ASIC / IC", "LAN", "Management Subsystem Health", "Battery"
|
||||
};
|
||||
static const char *sensor_type_desc[] __attribute__ ((unused)) = {
|
||||
"reserved",
|
||||
"Temperature", "Voltage", "Current", "Fan",
|
||||
"Physical Security", "Platform Security", "Processor",
|
||||
"Power Supply", "Power Unit", "Cooling Device", "Other",
|
||||
"Memory", "Drive Slot / Bay", "POST Memory Resize",
|
||||
"System Firmwares", "Event Logging Disabled", "Watchdog",
|
||||
"System Event", "Critical Interrupt", "Button",
|
||||
"Module / Board", "Microcontroller", "Add-in Card",
|
||||
"Chassis", "Chip Set", "Other FRU", "Cable / Interconnect",
|
||||
"Terminator", "System Boot Initiated", "Boot Error",
|
||||
"OS Boot", "OS Critical Stop", "Slot / Connector",
|
||||
"System ACPI Power State", "Watchdog", "Platform Alert",
|
||||
"Entity Presence", "Monitor ASIC", "LAN",
|
||||
"Management Subsystem Health", "Battery"};
|
||||
|
||||
struct ipmi_sdr_iterator * ipmi_sdr_start(struct ipmi_intf * intf);
|
||||
struct sdr_get_rs * ipmi_sdr_get_next_header(struct ipmi_intf * intf, struct ipmi_sdr_iterator * i);
|
||||
uint8_t * ipmi_sdr_get_record(struct ipmi_intf * intf, struct sdr_get_rs * header, struct ipmi_sdr_iterator * i);
|
||||
void ipmi_sdr_end(struct ipmi_intf * intf, struct ipmi_sdr_iterator * i);
|
||||
int ipmi_sdr_print_sdr(struct ipmi_intf * intf, uint8_t type);
|
||||
int ipmi_sdr_print_rawentry(struct ipmi_intf * intf, uint8_t type, uint8_t * raw, int len);
|
||||
int ipmi_sdr_print_listentry(struct ipmi_intf * intf, struct sdr_record_list * entry);
|
||||
const char * ipmi_sdr_get_status(uint8_t stat);
|
||||
float sdr_convert_sensor_reading(struct sdr_record_full_sensor * sensor, uint8_t val);
|
||||
uint8_t sdr_convert_sensor_value_to_raw(struct sdr_record_full_sensor * sensor, float val);
|
||||
struct ipmi_rs * ipmi_sdr_get_sensor_reading(struct ipmi_intf * intf, uint8_t sensor);
|
||||
const char * ipmi_sdr_get_sensor_type_desc(const uint8_t type);
|
||||
struct ipmi_sdr_iterator *ipmi_sdr_start(struct ipmi_intf *intf);
|
||||
struct sdr_get_rs *ipmi_sdr_get_next_header(struct ipmi_intf *intf,
|
||||
struct ipmi_sdr_iterator *i);
|
||||
uint8_t *ipmi_sdr_get_record(struct ipmi_intf *intf, struct sdr_get_rs *header,
|
||||
struct ipmi_sdr_iterator *i);
|
||||
void ipmi_sdr_end(struct ipmi_intf *intf, struct ipmi_sdr_iterator *i);
|
||||
int ipmi_sdr_print_sdr(struct ipmi_intf *intf, uint8_t type);
|
||||
int ipmi_sdr_print_rawentry(struct ipmi_intf *intf, uint8_t type, uint8_t * raw,
|
||||
int len);
|
||||
int ipmi_sdr_print_listentry(struct ipmi_intf *intf,
|
||||
struct sdr_record_list *entry);
|
||||
char *ipmi_sdr_get_unit_string(uint8_t type, uint8_t base, uint8_t modifier);
|
||||
const char *ipmi_sdr_get_status(struct sdr_record_full_sensor *sensor,
|
||||
uint8_t stat);
|
||||
double sdr_convert_sensor_reading(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,
|
||||
uint8_t sensor);
|
||||
struct ipmi_rs *ipmi_sdr_get_sensor_reading_ipmb(struct ipmi_intf *intf,
|
||||
uint8_t sensor,
|
||||
uint8_t target);
|
||||
struct ipmi_rs *ipmi_sdr_get_sensor_thresholds(struct ipmi_intf *intf,
|
||||
uint8_t sensor);
|
||||
struct ipmi_rs *ipmi_sdr_get_sensor_hysteresis(struct ipmi_intf *intf,
|
||||
uint8_t sensor);
|
||||
const char *ipmi_sdr_get_sensor_type_desc(const uint8_t type);
|
||||
int ipmi_sdr_get_reservation(struct ipmi_intf *intf, uint16_t * reserve_id);
|
||||
|
||||
int ipmi_sdr_print_sensor_full(struct ipmi_intf * intf, struct sdr_record_full_sensor * sensor);
|
||||
int ipmi_sdr_print_sensor_compact(struct ipmi_intf * intf, struct sdr_record_compact_sensor * sensor);
|
||||
int ipmi_sdr_print_sensor_eventonly(struct ipmi_intf * intf, struct sdr_record_eventonly_sensor * sensor);
|
||||
int ipmi_sdr_print_sensor_fru_locator(struct ipmi_intf * intf, struct sdr_record_fru_locator * fru);
|
||||
int ipmi_sdr_print_sensor_mc_locator(struct ipmi_intf * intf, struct sdr_record_mc_locator * mc);
|
||||
int ipmi_sdr_print_sensor_full(struct ipmi_intf *intf,
|
||||
struct sdr_record_full_sensor *sensor);
|
||||
int ipmi_sdr_print_sensor_compact(struct ipmi_intf *intf,
|
||||
struct sdr_record_compact_sensor *sensor);
|
||||
int ipmi_sdr_print_sensor_eventonly(struct ipmi_intf *intf,
|
||||
struct sdr_record_eventonly_sensor *sensor);
|
||||
int ipmi_sdr_print_sensor_generic_locator(struct ipmi_intf *intf,
|
||||
struct sdr_record_generic_locator
|
||||
*fru);
|
||||
int ipmi_sdr_print_sensor_fru_locator(struct ipmi_intf *intf,
|
||||
struct sdr_record_fru_locator *fru);
|
||||
int ipmi_sdr_print_sensor_mc_locator(struct ipmi_intf *intf,
|
||||
struct sdr_record_mc_locator *mc);
|
||||
int ipmi_sdr_print_sensor_entity_assoc(struct ipmi_intf *intf,
|
||||
struct sdr_record_entity_assoc *assoc);
|
||||
|
||||
struct sdr_record_list * ipmi_sdr_find_sdr_byentity(struct ipmi_intf * intf, struct entity_id * entity);
|
||||
struct sdr_record_list * ipmi_sdr_find_sdr_bynumtype(struct ipmi_intf * intf, uint8_t num, uint8_t type);
|
||||
struct sdr_record_list * ipmi_sdr_find_sdr_byid(struct ipmi_intf * intf, char * id);
|
||||
void ipmi_sdr_list_empty(struct ipmi_intf * intf);
|
||||
int ipmi_sdr_print_info(struct ipmi_intf * intf);
|
||||
void ipmi_sdr_print_discrete_state(uint8_t sensor_type, uint8_t event_type, uint8_t state);
|
||||
struct sdr_record_list *ipmi_sdr_find_sdr_byentity(struct ipmi_intf *intf,
|
||||
struct entity_id *entity);
|
||||
struct sdr_record_list *ipmi_sdr_find_sdr_bynumtype(struct ipmi_intf *intf,
|
||||
uint8_t num, uint8_t type);
|
||||
struct sdr_record_list *ipmi_sdr_find_sdr_bysensortype(struct ipmi_intf *intf,
|
||||
uint8_t type);
|
||||
struct sdr_record_list *ipmi_sdr_find_sdr_byid(struct ipmi_intf *intf,
|
||||
char *id);
|
||||
struct sdr_record_list *ipmi_sdr_find_sdr_bytype(struct ipmi_intf *intf,
|
||||
uint8_t type);
|
||||
int ipmi_sdr_list_cache(struct ipmi_intf *intf);
|
||||
int ipmi_sdr_list_cache_fromfile(struct ipmi_intf *intf, const char *ifile);
|
||||
void ipmi_sdr_list_empty(struct ipmi_intf *intf);
|
||||
int ipmi_sdr_print_info(struct ipmi_intf *intf);
|
||||
void ipmi_sdr_print_discrete_state(const char *desc, uint8_t sensor_type,
|
||||
uint8_t event_type, uint8_t state1,
|
||||
uint8_t state2);
|
||||
void ipmi_sdr_print_discrete_state_mini(const char *separator,
|
||||
uint8_t sensor_type, uint8_t event_type,
|
||||
uint8_t state1, uint8_t state2);
|
||||
int ipmi_sdr_print_sensor_event_status(struct ipmi_intf *intf,
|
||||
uint8_t sensor_num, uint8_t sensor_type,
|
||||
uint8_t event_type, int numeric_fmt);
|
||||
int ipmi_sdr_print_sensor_event_enable(struct ipmi_intf *intf,
|
||||
uint8_t sensor_num, uint8_t sensor_type,
|
||||
uint8_t event_type, int numeric_fmt);
|
||||
|
||||
#endif /* IPMI_SDR_H */
|
||||
|
@ -39,6 +39,7 @@
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <ipmitool/ipmi.h>
|
||||
#include <ipmitool/ipmi_sdr.h>
|
||||
|
||||
#define IPMI_CMD_GET_SEL_INFO 0x40
|
||||
#define IPMI_CMD_GET_SEL_ALLOC_INFO 0x41
|
||||
@ -67,36 +68,45 @@ struct sel_get_rq {
|
||||
uint8_t length;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct sel_event_record {
|
||||
uint16_t record_id;
|
||||
uint8_t record_type;
|
||||
struct standard_spec_sel_rec{
|
||||
uint32_t timestamp;
|
||||
uint16_t gen_id;
|
||||
uint8_t evm_rev;
|
||||
uint8_t sensor_type;
|
||||
uint8_t sensor_num;
|
||||
#if WORDS_BIGENDIAN
|
||||
uint8_t event_dir : 1;
|
||||
uint8_t event_type : 7;
|
||||
#else
|
||||
uint8_t event_type : 7;
|
||||
uint8_t event_dir : 1;
|
||||
#endif
|
||||
#define DATA_BYTE2_SPECIFIED_MASK 0xc0 /* event_data[0] bit mask */
|
||||
#define DATA_BYTE3_SPECIFIED_MASK 0x30 /* event_data[0] bit mask */
|
||||
#define EVENT_OFFSET_MASK 0x0f /* event_data[0] bit mask */
|
||||
uint8_t event_data[3];
|
||||
} __attribute__ ((packed));
|
||||
};
|
||||
|
||||
struct sel_oem_record_ts {
|
||||
uint16_t next_id;
|
||||
uint16_t record_id;
|
||||
uint8_t record_type;
|
||||
#define SEL_OEM_TS_DATA_LEN 6
|
||||
#define SEL_OEM_NOTS_DATA_LEN 13
|
||||
struct oem_ts_spec_sel_rec{
|
||||
uint32_t timestamp;
|
||||
uint8_t mfg_id[3];
|
||||
uint8_t oem_defined[6];
|
||||
} __attribute__ ((packed));
|
||||
uint8_t manf_id[3];
|
||||
uint8_t oem_defined[SEL_OEM_TS_DATA_LEN];
|
||||
};
|
||||
|
||||
struct sel_oem_record_nots {
|
||||
uint16_t next_id;
|
||||
struct oem_nots_spec_sel_rec{
|
||||
uint8_t oem_defined[SEL_OEM_NOTS_DATA_LEN];
|
||||
};
|
||||
|
||||
struct sel_event_record {
|
||||
uint16_t record_id;
|
||||
uint8_t record_type;
|
||||
uint8_t oem_defined[13];
|
||||
union{
|
||||
struct standard_spec_sel_rec standard_type;
|
||||
struct oem_ts_spec_sel_rec oem_ts_type;
|
||||
struct oem_nots_spec_sel_rec oem_nots_type;
|
||||
} sel_type;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct ipmi_event_sensor_types {
|
||||
@ -111,18 +121,18 @@ struct ipmi_event_sensor_types {
|
||||
|
||||
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" },
|
||||
{ 0x01, 0x01, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Lower Non-critical - going high" },
|
||||
{ 0x01, 0x02, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Lower Critical - going low" },
|
||||
{ 0x01, 0x03, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Lower Critical - going high" },
|
||||
{ 0x01, 0x04, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Lower Non-recoverable - going low" },
|
||||
{ 0x01, 0x05, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Lower Non-recoverable - going high" },
|
||||
{ 0x01, 0x06, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Upper Non-critical - going low" },
|
||||
{ 0x01, 0x07, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Upper Non-critical - going high" },
|
||||
{ 0x01, 0x08, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Upper Critical - going low" },
|
||||
{ 0x01, 0x09, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Upper Critical - going high" },
|
||||
{ 0x01, 0x0a, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Upper Non-recoverable - going low" },
|
||||
{ 0x01, 0x0b, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Upper Non-recoverable - going high" },
|
||||
{ 0x01, 0x00, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Lower Non-critical going low " },
|
||||
{ 0x01, 0x01, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Lower Non-critical going high" },
|
||||
{ 0x01, 0x02, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Lower Critical going low " },
|
||||
{ 0x01, 0x03, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Lower Critical going high" },
|
||||
{ 0x01, 0x04, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Lower Non-recoverable going low " },
|
||||
{ 0x01, 0x05, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Lower Non-recoverable going high" },
|
||||
{ 0x01, 0x06, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Upper Non-critical going low " },
|
||||
{ 0x01, 0x07, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Upper Non-critical going high" },
|
||||
{ 0x01, 0x08, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Upper Critical going low " },
|
||||
{ 0x01, 0x09, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Upper Critical going high" },
|
||||
{ 0x01, 0x0a, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Upper Non-recoverable going low " },
|
||||
{ 0x01, 0x0b, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Upper Non-recoverable going high" },
|
||||
/* DMI-based "usage state" States */
|
||||
{ 0x02, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Usage State", "Transition to Idle" },
|
||||
{ 0x02, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Usage State", "Transition to Active" },
|
||||
@ -147,8 +157,8 @@ static struct ipmi_event_sensor_types generic_event_types[] __attribute__((unuse
|
||||
{ 0x07, 0x07, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Severity State", "Monitor" },
|
||||
{ 0x07, 0x08, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Severity State", "Informational" },
|
||||
/* Availability Status States */
|
||||
{ 0x08, 0x00, 0xff, IPMI_EVENT_CLASS_DIGITAL, "Availability State", "Device Removed/Absent" },
|
||||
{ 0x08, 0x01, 0xff, IPMI_EVENT_CLASS_DIGITAL, "Availability State", "Device Inserted/Present" },
|
||||
{ 0x08, 0x00, 0xff, IPMI_EVENT_CLASS_DIGITAL, "Availability State", "Device Absent" },
|
||||
{ 0x08, 0x01, 0xff, IPMI_EVENT_CLASS_DIGITAL, "Availability State", "Device Present" },
|
||||
{ 0x09, 0x00, 0xff, IPMI_EVENT_CLASS_DIGITAL, "Availability State", "Device Disabled" },
|
||||
{ 0x09, 0x01, 0xff, IPMI_EVENT_CLASS_DIGITAL, "Availability State", "Device Enabled" },
|
||||
{ 0x0a, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Availability State", "Transition to Running" },
|
||||
@ -190,7 +200,7 @@ static struct ipmi_event_sensor_types sensor_specific_types[] __attribute__((unu
|
||||
{ 0x05, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Physical Security", "I/O Card area intrusion" },
|
||||
{ 0x05, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Physical Security", "Processor area intrusion" },
|
||||
{ 0x05, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Physical Security", "System unplugged from LAN" },
|
||||
{ 0x05, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Physical Security", "Unauthorized dock/undock" },
|
||||
{ 0x05, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Physical Security", "Unauthorized dock" },
|
||||
{ 0x05, 0x06, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Physical Security", "FAN area intrusion" },
|
||||
|
||||
{ 0x06, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Platform Security", "Front Panel Lockout violation attempted" },
|
||||
@ -210,6 +220,7 @@ static struct ipmi_event_sensor_types sensor_specific_types[] __attribute__((unu
|
||||
{ 0x07, 0x07, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Processor", "Presence detected" },
|
||||
{ 0x07, 0x08, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Processor", "Disabled" },
|
||||
{ 0x07, 0x09, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Processor", "Terminator presence detected" },
|
||||
{ 0x07, 0x0a, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Processor", "Throttled" },
|
||||
|
||||
{ 0x08, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Power Supply", "Presence detected" },
|
||||
{ 0x08, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Power Supply", "Failure detected" },
|
||||
@ -217,6 +228,10 @@ static struct ipmi_event_sensor_types sensor_specific_types[] __attribute__((unu
|
||||
{ 0x08, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Power Supply", "Power Supply AC lost" },
|
||||
{ 0x08, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Power Supply", "AC lost or out-of-range" },
|
||||
{ 0x08, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Power Supply", "AC out-of-range, but present" },
|
||||
{ 0x08, 0x06, 0x00, IPMI_EVENT_CLASS_DISCRETE, "Power Supply", "Config Error: Vendor Mismatch" },
|
||||
{ 0x08, 0x06, 0x01, IPMI_EVENT_CLASS_DISCRETE, "Power Supply", "Config Error: Revision Mismatch" },
|
||||
{ 0x08, 0x06, 0x02, IPMI_EVENT_CLASS_DISCRETE, "Power Supply", "Config Error: Processor Missing" },
|
||||
{ 0x08, 0x06, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Power Supply", "Config Error" },
|
||||
|
||||
{ 0x09, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Power Unit", "Power off/down" },
|
||||
{ 0x09, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Power Unit", "Power cycle" },
|
||||
@ -236,31 +251,108 @@ static struct ipmi_event_sensor_types sensor_specific_types[] __attribute__((unu
|
||||
{ 0x0c, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Memory", "Memory Scrub Failed" },
|
||||
{ 0x0c, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Memory", "Memory Device Disabled" },
|
||||
{ 0x0c, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Memory", "Correctable ECC logging limit reached" },
|
||||
{ 0x0c, 0x06, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Memory", "Presence Detected" },
|
||||
{ 0x0c, 0x07, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Memory", "Configuration Error" },
|
||||
{ 0x0c, 0x08, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Memory", "Spare" },
|
||||
{ 0x0c, 0x09, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Memory", "Throttled" },
|
||||
|
||||
{ 0x0d, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Drive Slot", "Drive Present" },
|
||||
{ 0x0d, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Drive Slot", "Drive Fault" },
|
||||
{ 0x0d, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Drive Slot", "Predictive Failure" },
|
||||
{ 0x0d, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Drive Slot", "Hot Spare" },
|
||||
{ 0x0d, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Drive Slot", "Parity Check In Progress" },
|
||||
{ 0x0d, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Drive Slot", "In Critical Array" },
|
||||
{ 0x0d, 0x06, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Drive Slot", "In Failed Array" },
|
||||
{ 0x0d, 0x07, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Drive Slot", "Rebuild In Progress" },
|
||||
{ 0x0d, 0x08, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Drive Slot", "Rebuild Aborted" },
|
||||
|
||||
{ 0x0d, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Drive Slot", NULL },
|
||||
{ 0x0e, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "POST Memory Resize", NULL },
|
||||
|
||||
{ 0x0f, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Firmware", "Error" },
|
||||
{ 0x0f, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Firmware", "Hang" },
|
||||
{ 0x0f, 0x02, 0x00, IPMI_EVENT_CLASS_DISCRETE, "System Firmware", "Progress 1" },
|
||||
{ 0x0f, 0x02, 0x01, IPMI_EVENT_CLASS_DISCRETE, "System Firmware", "Progress 2" },
|
||||
{ 0x0f, 0x02, 0x02, IPMI_EVENT_CLASS_DISCRETE, "System Firmware", "Progress 3" },
|
||||
{ 0x0f, 0x02, 0x03, IPMI_EVENT_CLASS_DISCRETE, "System Firmware", "Progress 4" },
|
||||
{ 0x0f, 0x02, 0x04, IPMI_EVENT_CLASS_DISCRETE, "System Firmware", "Progress 5" },
|
||||
{ 0x0f, 0x02, 0x13, IPMI_EVENT_CLASS_DISCRETE, "System Firmware", "System Boot Initiated" },
|
||||
{ 0x0f, 0x00, 0x00, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Error", "Unspecified" },
|
||||
{ 0x0f, 0x00, 0x01, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Error", "No system memory installed" },
|
||||
{ 0x0f, 0x00, 0x02, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Error", "No usable system memory" },
|
||||
{ 0x0f, 0x00, 0x03, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Error", "Unrecoverable IDE device failure" },
|
||||
{ 0x0f, 0x00, 0x04, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Error", "Unrecoverable system-board failure" },
|
||||
{ 0x0f, 0x00, 0x05, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Error", "Unrecoverable diskette failure" },
|
||||
{ 0x0f, 0x00, 0x06, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Error", "Unrecoverable hard-disk controller failure" },
|
||||
{ 0x0f, 0x00, 0x07, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Error", "Unrecoverable PS/2 or USB keyboard failure" },
|
||||
{ 0x0f, 0x00, 0x08, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Error", "Removable boot media not found" },
|
||||
{ 0x0f, 0x00, 0x09, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Error", "Unrecoverable video controller failure" },
|
||||
{ 0x0f, 0x00, 0x0a, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Error", "No video device selected" },
|
||||
{ 0x0f, 0x00, 0x0b, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Error", "BIOS corruption detected" },
|
||||
{ 0x0f, 0x00, 0x0c, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Error", "CPU voltage mismatch" },
|
||||
{ 0x0f, 0x00, 0x0d, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Error", "CPU speed mismatch failure" },
|
||||
{ 0x0f, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Error", "Unknown Error" },
|
||||
|
||||
{ 0x0f, 0x01, 0x00, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Unspecified" },
|
||||
{ 0x0f, 0x01, 0x01, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Memory initialization" },
|
||||
{ 0x0f, 0x01, 0x02, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Hard-disk initialization" },
|
||||
{ 0x0f, 0x01, 0x03, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Secondary CPU Initialization" },
|
||||
{ 0x0f, 0x01, 0x04, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "User authentication" },
|
||||
{ 0x0f, 0x01, 0x05, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "User-initiated system setup" },
|
||||
{ 0x0f, 0x01, 0x06, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "USB resource configuration" },
|
||||
{ 0x0f, 0x01, 0x07, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "PCI resource configuration" },
|
||||
{ 0x0f, 0x01, 0x08, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Option ROM initialization" },
|
||||
{ 0x0f, 0x01, 0x09, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Video initialization" },
|
||||
{ 0x0f, 0x01, 0x0a, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Cache initialization" },
|
||||
{ 0x0f, 0x01, 0x0b, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "SMBus initialization" },
|
||||
{ 0x0f, 0x01, 0x0c, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Keyboard controller initialization" },
|
||||
{ 0x0f, 0x01, 0x0d, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Management controller initialization" },
|
||||
{ 0x0f, 0x01, 0x0e, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Docking station attachment" },
|
||||
{ 0x0f, 0x01, 0x0f, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Enabling docking station" },
|
||||
{ 0x0f, 0x01, 0x10, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Docking station ejection" },
|
||||
{ 0x0f, 0x01, 0x11, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Disabling docking station" },
|
||||
{ 0x0f, 0x01, 0x12, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Calling operating system wake-up vector" },
|
||||
{ 0x0f, 0x01, 0x13, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "System boot initiated" },
|
||||
{ 0x0f, 0x01, 0x14, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Motherboard initialization" },
|
||||
{ 0x0f, 0x01, 0x15, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "reserved" },
|
||||
{ 0x0f, 0x01, 0x16, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Floppy initialization" },
|
||||
{ 0x0f, 0x01, 0x17, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Keyboard test" },
|
||||
{ 0x0f, 0x01, 0x18, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Pointing device test" },
|
||||
{ 0x0f, 0x01, 0x19, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Primary CPU initialization" },
|
||||
{ 0x0f, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Unknown Hang" },
|
||||
|
||||
{ 0x0f, 0x02, 0x00, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Unspecified" },
|
||||
{ 0x0f, 0x02, 0x01, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Memory initialization" },
|
||||
{ 0x0f, 0x02, 0x02, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Hard-disk initialization" },
|
||||
{ 0x0f, 0x02, 0x03, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Secondary CPU Initialization" },
|
||||
{ 0x0f, 0x02, 0x04, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "User authentication" },
|
||||
{ 0x0f, 0x02, 0x05, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "User-initiated system setup" },
|
||||
{ 0x0f, 0x02, 0x06, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "USB resource configuration" },
|
||||
{ 0x0f, 0x02, 0x07, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "PCI resource configuration" },
|
||||
{ 0x0f, 0x02, 0x08, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Option ROM initialization" },
|
||||
{ 0x0f, 0x02, 0x09, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Video initialization" },
|
||||
{ 0x0f, 0x02, 0x0a, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Cache initialization" },
|
||||
{ 0x0f, 0x02, 0x0b, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "SMBus initialization" },
|
||||
{ 0x0f, 0x02, 0x0c, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Keyboard controller initialization" },
|
||||
{ 0x0f, 0x02, 0x0d, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Management controller initialization" },
|
||||
{ 0x0f, 0x02, 0x0e, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Docking station attachment" },
|
||||
{ 0x0f, 0x02, 0x0f, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Enabling docking station" },
|
||||
{ 0x0f, 0x02, 0x10, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Docking station ejection" },
|
||||
{ 0x0f, 0x02, 0x11, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Disabling docking station" },
|
||||
{ 0x0f, 0x02, 0x12, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Calling operating system wake-up vector" },
|
||||
{ 0x0f, 0x02, 0x13, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "System boot initiated" },
|
||||
{ 0x0f, 0x02, 0x14, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Motherboard initialization" },
|
||||
{ 0x0f, 0x02, 0x15, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "reserved" },
|
||||
{ 0x0f, 0x02, 0x16, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Floppy initialization" },
|
||||
{ 0x0f, 0x02, 0x17, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Keyboard test" },
|
||||
{ 0x0f, 0x02, 0x18, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Pointing device test" },
|
||||
{ 0x0f, 0x02, 0x19, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Primary CPU initialization" },
|
||||
{ 0x0f, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Unknown Progress" },
|
||||
|
||||
{ 0x10, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Event Logging Disabled", "Correctable memory error logging disabled" },
|
||||
{ 0x10, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Event Logging Disabled", "Event logging disabled" },
|
||||
{ 0x10, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Event Logging Disabled", "Log area reset/cleared" },
|
||||
{ 0x10, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Event Logging Disabled", "All event logging disabled" },
|
||||
{ 0x10, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Event Logging Disabled", "Log full" },
|
||||
{ 0x10, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Event Logging Disabled", "Log almost full" },
|
||||
|
||||
{ 0x11, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Watchdog 1", "BIOS Reset" },
|
||||
{ 0x11, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Watchdog 1", "OS Reset" },
|
||||
{ 0x11, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Watchdog 1", "OS Shut Down" },
|
||||
{ 0x11, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Watchdog 1", "OS Power Down" },
|
||||
{ 0x11, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Watchdog 1", "OS Power Cycle" },
|
||||
{ 0x11, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Watchdog 1", "OS NMI/diag Interrupt" },
|
||||
{ 0x11, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Watchdog 1", "OS NMI/Diag Interrupt" },
|
||||
{ 0x11, 0x06, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Watchdog 1", "OS Expired" },
|
||||
{ 0x11, 0x07, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Watchdog 1", "OS pre-timeout Interrupt" },
|
||||
|
||||
@ -269,9 +361,9 @@ static struct ipmi_event_sensor_types sensor_specific_types[] __attribute__((unu
|
||||
{ 0x12, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Event", "Undetermined system hardware failure" },
|
||||
{ 0x12, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Event", "Entry added to auxiliary log" },
|
||||
{ 0x12, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Event", "PEF Action" },
|
||||
{ 0x12, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Event", "Timestamp Clock Sync." },
|
||||
{ 0x12, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Event", "Timestamp Clock Sync" },
|
||||
|
||||
{ 0x13, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Critical Interrupt", "Front Panel NMI" },
|
||||
{ 0x13, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Critical Interrupt", "NMI/Diag Interrupt" },
|
||||
{ 0x13, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Critical Interrupt", "Bus Timeout" },
|
||||
{ 0x13, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Critical Interrupt", "I/O Channel check NMI" },
|
||||
{ 0x13, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Critical Interrupt", "Software NMI" },
|
||||
@ -281,10 +373,13 @@ static struct ipmi_event_sensor_types sensor_specific_types[] __attribute__((unu
|
||||
{ 0x13, 0x07, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Critical Interrupt", "Bus Correctable error" },
|
||||
{ 0x13, 0x08, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Critical Interrupt", "Bus Uncorrectable error" },
|
||||
{ 0x13, 0x09, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Critical Interrupt", "Fatal NMI" },
|
||||
{ 0x13, 0x0a, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Critical Interrupt", "Bus Fatal Error" },
|
||||
|
||||
{ 0x14, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Button", "Power Button pressed" },
|
||||
{ 0x14, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Button", "Sleep Button pressed" },
|
||||
{ 0x14, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Button", "Reset Button pressed" },
|
||||
{ 0x14, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Button", "FRU Latch" },
|
||||
{ 0x14, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Button", "FRU Service" },
|
||||
|
||||
{ 0x15, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Module/Board", NULL },
|
||||
{ 0x16, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Microcontroller/Coprocessor", NULL },
|
||||
@ -292,7 +387,10 @@ static struct ipmi_event_sensor_types sensor_specific_types[] __attribute__((unu
|
||||
{ 0x18, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Chassis", NULL },
|
||||
{ 0x19, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Chip Set", NULL },
|
||||
{ 0x1a, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Other FRU", NULL },
|
||||
{ 0x1b, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Cable/Interconnect", NULL },
|
||||
|
||||
{ 0x1b, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Cable/Interconnect", "Connected" },
|
||||
{ 0x1b, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Cable/Interconnect", "Config Error" },
|
||||
|
||||
{ 0x1c, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Terminator", NULL },
|
||||
|
||||
{ 0x1d, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Boot Initiated", "Initiated by power up" },
|
||||
@ -300,6 +398,9 @@ static struct ipmi_event_sensor_types sensor_specific_types[] __attribute__((unu
|
||||
{ 0x1d, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Boot Initiated", "Initiated by warm reset" },
|
||||
{ 0x1d, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Boot Initiated", "User requested PXE boot" },
|
||||
{ 0x1d, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Boot Initiated", "Automatic boot to diagnostic" },
|
||||
{ 0x1d, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Boot Initiated", "OS initiated hard reset" },
|
||||
{ 0x1d, 0x06, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Boot Initiated", "OS initiated warm reset" },
|
||||
{ 0x1d, 0x07, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Boot Initiated", "System Restart" },
|
||||
|
||||
{ 0x1e, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Boot Error", "No bootable media" },
|
||||
{ 0x1e, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Boot Error", "Non-bootable disk in drive" },
|
||||
@ -315,18 +416,23 @@ static struct ipmi_event_sensor_types sensor_specific_types[] __attribute__((unu
|
||||
{ 0x1f, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "OS Boot", "ROM boot completed" },
|
||||
{ 0x1f, 0x06, 0xff, IPMI_EVENT_CLASS_DISCRETE, "OS Boot", "boot completed - device not specified" },
|
||||
|
||||
{ 0x20, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "OS Critical Stop", "Stop during OS load/init" },
|
||||
{ 0x20, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "OS Critical Stop", "Run-time stop" },
|
||||
{ 0x20, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "OS Stop/Shutdown", "Error during system startup" },
|
||||
{ 0x20, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "OS Stop/Shutdown", "Run-time critical stop" },
|
||||
{ 0x20, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "OS Stop/Shutdown", "OS graceful stop" },
|
||||
{ 0x20, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "OS Stop/Shutdown", "OS graceful shutdown" },
|
||||
{ 0x20, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "OS Stop/Shutdown", "PEF initiated soft shutdown" },
|
||||
{ 0x20, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "OS Stop/Shutdown", "Agent not responding" },
|
||||
|
||||
{ 0x21, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Fault Status asserted" },
|
||||
{ 0x21, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Identify Status asserted" },
|
||||
{ 0x21, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Device installed/attached" },
|
||||
{ 0x21, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Ready for device installation" },
|
||||
{ 0x21, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Ready for device removal" },
|
||||
{ 0x21, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Slot Power is off" },
|
||||
{ 0x21, 0x06, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Device removal request" },
|
||||
{ 0x21, 0x07, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Interlock asserted" },
|
||||
{ 0x21, 0x08, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Slot is disabled" },
|
||||
{ 0x21, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Fault Status" },
|
||||
{ 0x21, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Identify Status" },
|
||||
{ 0x21, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Device Installed" },
|
||||
{ 0x21, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Ready for Device Installation" },
|
||||
{ 0x21, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Ready for Device Removal" },
|
||||
{ 0x21, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Slot Power is Off" },
|
||||
{ 0x21, 0x06, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Device Removal Request" },
|
||||
{ 0x21, 0x07, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Interlock" },
|
||||
{ 0x21, 0x08, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Slot is Disabled" },
|
||||
{ 0x21, 0x09, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Spare Device" },
|
||||
|
||||
{ 0x22, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System ACPI Power State", "S0/G0: working" },
|
||||
{ 0x22, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System ACPI Power State", "S1: sleeping with system hw & processor context maintained" },
|
||||
@ -371,18 +477,77 @@ static struct ipmi_event_sensor_types sensor_specific_types[] __attribute__((unu
|
||||
{ 0x28, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Management Subsystem Health", "Controller access degraded or unavailable" },
|
||||
{ 0x28, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Management Subsystem Health", "Management controller off-line" },
|
||||
{ 0x28, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Management Subsystem Health", "Management controller unavailable" },
|
||||
{ 0x28, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Management Subsystem Health", "Sensor failure" },
|
||||
{ 0x28, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Management Subsystem Health", "FRU failure" },
|
||||
|
||||
{ 0x29, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Battery", "Low" },
|
||||
{ 0x29, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Battery", "Failed" },
|
||||
{ 0x29, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Battery", "Presence Detected" },
|
||||
|
||||
{ 0x2b, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Version Change", "Hardware change detected" },
|
||||
{ 0x2b, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Version Change", "Firmware or software change detected" },
|
||||
{ 0x2b, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Version Change", "Hardware incompatibility detected" },
|
||||
{ 0x2b, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Version Change", "Firmware or software incompatibility detected" },
|
||||
{ 0x2b, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Version Change", "Invalid or unsupported hardware version" },
|
||||
{ 0x2b, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Version Change", "Invalid or unsupported firmware or software version" },
|
||||
{ 0x2b, 0x06, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Version Change", "Hardware change success" },
|
||||
{ 0x2b, 0x07, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Version Change", "Firmware or software change success" },
|
||||
|
||||
{ 0x2c, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "FRU State", "Not Installed" },
|
||||
{ 0x2c, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "FRU State", "Inactive" },
|
||||
{ 0x2c, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "FRU State", "Activation Requested" },
|
||||
{ 0x2c, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "FRU State", "Activation in Progress" },
|
||||
{ 0x2c, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "FRU State", "Active" },
|
||||
{ 0x2c, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "FRU State", "Deactivation Requested" },
|
||||
{ 0x2c, 0x06, 0xff, IPMI_EVENT_CLASS_DISCRETE, "FRU State", "Deactivation in Progress" },
|
||||
{ 0x2c, 0x07, 0xff, IPMI_EVENT_CLASS_DISCRETE, "FRU State", "Communication lost" },
|
||||
|
||||
{ 0xF0, 0x00, 0xFF, IPMI_EVENT_CLASS_DISCRETE, "FRU Hot Swap", "Transition to M0" },
|
||||
{ 0xF0, 0x01, 0xFF, IPMI_EVENT_CLASS_DISCRETE, "FRU Hot Swap", "Transition to M1" },
|
||||
{ 0xF0, 0x02, 0xFF, IPMI_EVENT_CLASS_DISCRETE, "FRU Hot Swap", "Transition to M2" },
|
||||
{ 0xF0, 0x03, 0xFF, IPMI_EVENT_CLASS_DISCRETE, "FRU Hot Swap", "Transition to M3" },
|
||||
{ 0xF0, 0x04, 0xFF, IPMI_EVENT_CLASS_DISCRETE, "FRU Hot Swap", "Transition to M4" },
|
||||
{ 0xF0, 0x05, 0xFF, IPMI_EVENT_CLASS_DISCRETE, "FRU Hot Swap", "Transition to M5" },
|
||||
{ 0xF0, 0x06, 0xFF, IPMI_EVENT_CLASS_DISCRETE, "FRU Hot Swap", "Transition to M6" },
|
||||
{ 0xF0, 0x06, 0xFF, IPMI_EVENT_CLASS_DISCRETE, "FRU Hot Swap", "Transition to M7" },
|
||||
|
||||
{ 0xF1, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "IPMB-0 Status", "IPMB-A disabled, IPMB-B disabled" },
|
||||
{ 0xF1, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "IPMB-0 Status", "IPMB-A enabled, IPMB-B disabled" },
|
||||
{ 0xF1, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "IPMB-0 Status", "IPMB-A disabled, IPMB-B enabled" },
|
||||
{ 0xF1, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "IPMB-0 Status", "IPMB-A enabled, IPMP-B enabled" },
|
||||
|
||||
{ 0xF2, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Module Hot Swap", "Module Handle Closed" },
|
||||
{ 0xF2, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Module Hot Swap", "Module Handle Opened" },
|
||||
{ 0xF2, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Module Hot Swap", "Quiesced" },
|
||||
|
||||
{ 0xC0, 0x00, 0xff, 0x00, "OEM", NULL },
|
||||
|
||||
{ 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 sel_event_record * evt);
|
||||
void ipmi_sel_print_std_entry_verbose(struct sel_event_record * evt);
|
||||
void ipmi_get_event_desc(struct sel_event_record * rec, char ** desc);
|
||||
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);
|
||||
void ipmi_sel_print_extended_entry(struct ipmi_intf * intf, struct sel_event_record * evt);
|
||||
void ipmi_sel_print_extended_entry_verbose(struct ipmi_intf * intf, struct sel_event_record * evt);
|
||||
void ipmi_get_event_desc(struct ipmi_intf * intf, struct sel_event_record * rec, char ** desc);
|
||||
const char * ipmi_sel_get_sensor_type(uint8_t code);
|
||||
const char * ipmi_sel_get_sensor_type_offset(uint8_t code, uint8_t offset);
|
||||
uint16_t ipmi_sel_get_std_entry(struct ipmi_intf * intf, uint16_t id, struct sel_event_record * evt);
|
||||
char * get_newisys_evt_desc(struct ipmi_intf * intf, struct sel_event_record * rec);
|
||||
IPMI_OEM ipmi_get_oem(struct ipmi_intf * intf);
|
||||
char * ipmi_get_oem_desc(struct ipmi_intf * intf, struct sel_event_record * rec);
|
||||
|
||||
#endif /* IPMI_SEL_H */
|
||||
|
@ -42,13 +42,6 @@
|
||||
#include <ipmitool/ipmi.h>
|
||||
#include <ipmitool/ipmi_sdr.h>
|
||||
|
||||
/* ipmi sensor commands */
|
||||
#define GET_SENSOR_READING 0x2d
|
||||
#define GET_SENSOR_FACTORS 0x23
|
||||
#define SET_SENSOR_THRESHOLDS 0x26
|
||||
#define GET_SENSOR_THRESHOLDS 0x27
|
||||
#define GET_SENSOR_TYPE 0x2f
|
||||
|
||||
/* threshold specification bits for analog sensors for get sensor threshold command
|
||||
* and set sensor threshold command
|
||||
*/
|
||||
|
@ -39,6 +39,7 @@
|
||||
|
||||
#include <ipmitool/ipmi.h>
|
||||
|
||||
#define SOL_ESCAPE_CHARACTER_DEFAULT '~'
|
||||
|
||||
#define IPMI_SOL_SERIAL_ALERT_MASK_SUCCEED 0x08
|
||||
#define IPMI_SOL_SERIAL_ALERT_MASK_DEFERRED 0x04
|
||||
|
@ -42,7 +42,7 @@
|
||||
extern const struct valstr completion_code_vals[];
|
||||
extern const struct valstr entity_id_vals[];
|
||||
extern const struct valstr entity_device_type_vals[];
|
||||
|
||||
extern const struct valstr ipmi_netfn_vals[];
|
||||
extern const struct valstr ipmi_channel_activity_type_vals[];
|
||||
extern const struct valstr ipmi_privlvl_vals[];
|
||||
extern const struct valstr impi_bit_rate_vals[];
|
||||
@ -51,5 +51,11 @@ extern const struct valstr ipmi_authtype_session_vals[];
|
||||
extern const struct valstr ipmi_authtype_vals[];
|
||||
extern const struct valstr ipmi_channel_protocol_vals[];
|
||||
extern const struct valstr ipmi_channel_medium_vals[];
|
||||
extern const struct valstr ipmi_chassis_power_control_vals[];
|
||||
extern const struct valstr ipmi_auth_algorithms[];
|
||||
extern const struct valstr ipmi_integrity_algorithms[];
|
||||
extern const struct valstr ipmi_encryption_algorithms[];
|
||||
extern const struct valstr ipmi_oem_info[];
|
||||
|
||||
|
||||
#endif /*IPMI_STRINGS_H*/
|
||||
|
61
ipmitool/include/ipmitool/ipmi_sunoem.h
Normal file
61
ipmitool/include/ipmitool/ipmi_sunoem.h
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef IPMI_SUNOEM_H
|
||||
#define IPMI_SUNOEM_H
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
#include <ipmitool/ipmi.h>
|
||||
#include <ipmitool/ipmi_sdr.h>
|
||||
|
||||
#define IPMI_NETFN_SUNOEM 0x2e
|
||||
|
||||
#define IPMI_SUNOEM_SET_SSH_KEY 0x01
|
||||
#define IPMI_SUNOEM_DEL_SSH_KEY 0x02
|
||||
#define IPMI_SUNOEM_GET_HEALTH_STATUS 0x10
|
||||
#define IPMI_SUNOEM_SET_FAN_SPEED 0x20
|
||||
#define IPMI_SUNOEM_LED_GET 0x21
|
||||
#define IPMI_SUNOEM_LED_SET 0x22
|
||||
|
||||
int ipmi_sunoem_main(struct ipmi_intf *, int, char **);
|
||||
|
||||
struct ipmi_rs * sunoem_led_get(struct ipmi_intf * intf, struct sdr_record_generic_locator * dev, int ledtype);
|
||||
struct ipmi_rs * sunoem_led_set(struct ipmi_intf * intf, struct sdr_record_generic_locator * dev, int ledtype, int ledmode);
|
||||
|
||||
#endif /*IPMI_SUNOEM_H*/
|
||||
|
50
ipmitool/include/ipmitool/ipmi_tsol.h
Normal file
50
ipmitool/include/ipmitool/ipmi_tsol.h
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2005 Tyan Computer Corp. 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.
|
||||
*/
|
||||
|
||||
#ifndef IPMI_TSOL_H
|
||||
#define IPMI_TSOL_H
|
||||
|
||||
#include <ipmitool/ipmi.h>
|
||||
|
||||
#define IPMI_TSOL_CMD_SENDKEY 0x03
|
||||
#define IPMI_TSOL_CMD_START 0x06
|
||||
#define IPMI_TSOL_CMD_STOP 0x02
|
||||
|
||||
#define IPMI_TSOL_DEF_PORT 6230
|
||||
|
||||
int ipmi_tsol_main(struct ipmi_intf *, int, char **);
|
||||
|
||||
#endif /* IPMI_TSOL_H */
|
@ -40,7 +40,9 @@ libipmitool_la_SOURCES = helper.c ipmi_sdr.c ipmi_sel.c ipmi_sol.c ipmi_pef.c \
|
||||
ipmi_lanp.c ipmi_fru.c ipmi_chassis.c ipmi_mc.c log.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_oem.c ipmi_isol.c ipmi_sunoem.c ipmi_fwum.c ipmi_picmg.c \
|
||||
ipmi_main.c ipmi_tsol.c
|
||||
|
||||
libipmitool_la_LDFLAGS = -export-dynamic
|
||||
libipmitool_la_LIBADD = -lm
|
||||
libipmitool_la_DEPENDENCIES =
|
||||
|
@ -733,6 +733,11 @@ ipmi_spd_print(struct ipmi_intf * intf, uint8_t id)
|
||||
if (rsp->ccode > 0) {
|
||||
printf(" Device not present (%s)\n",
|
||||
val2str(rsp->ccode, completion_code_vals));
|
||||
|
||||
/* Timeouts are acceptable. No DIMM in the socket */
|
||||
if (rsp->ccode == 0xc3)
|
||||
return 1;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -34,17 +34,28 @@
|
||||
* facility.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h> /* For TIOCNOTTY */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <strings.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PATHS_H
|
||||
# include <paths.h> /* For _PATH_TTY */
|
||||
#endif
|
||||
|
||||
#include <ipmitool/helper.h>
|
||||
#include <ipmitool/log.h>
|
||||
|
||||
@ -100,12 +111,11 @@ void printbuf(const uint8_t * buf, int len, const char * desc)
|
||||
const char * val2str(uint16_t val, const struct valstr *vs)
|
||||
{
|
||||
static char un_str[16];
|
||||
int i = 0;
|
||||
int i;
|
||||
|
||||
while (vs[i].str != NULL) {
|
||||
for (i = 0; vs[i].str != NULL; i++) {
|
||||
if (vs[i].val == val)
|
||||
return vs[i].str;
|
||||
i++;
|
||||
}
|
||||
|
||||
memset(un_str, 0, 16);
|
||||
@ -116,15 +126,111 @@ const char * val2str(uint16_t val, const struct valstr *vs)
|
||||
|
||||
uint16_t str2val(const char *str, const struct valstr *vs)
|
||||
{
|
||||
int i = 0;
|
||||
int i;
|
||||
|
||||
while (vs[i].str != NULL) {
|
||||
if (!strncasecmp(vs[i].str, str, strlen(str)))
|
||||
for (i = 0; vs[i].str != NULL; i++) {
|
||||
if (strncasecmp(vs[i].str, str, __maxlen(str, vs[i].str)) == 0)
|
||||
return vs[i].val;
|
||||
i++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return vs[i].val;
|
||||
}
|
||||
|
||||
/* print_valstr - print value string list to log or stdout
|
||||
*
|
||||
* @vs: value string list to print
|
||||
* @title: name of this value string list
|
||||
* @loglevel: what log level to print, -1 for stdout
|
||||
*/
|
||||
void
|
||||
print_valstr(const struct valstr * vs, const char * title, int loglevel)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (vs == NULL)
|
||||
return;
|
||||
|
||||
if (title != NULL) {
|
||||
if (loglevel < 0)
|
||||
printf("\n%s:\n\n");
|
||||
else
|
||||
lprintf(loglevel, "\n%s:\n", title);
|
||||
}
|
||||
|
||||
if (loglevel < 0) {
|
||||
printf(" VALUE\tHEX\tSTRING\n");
|
||||
printf("==============================================\n");
|
||||
} else {
|
||||
lprintf(loglevel, " VAL\tHEX\tSTRING");
|
||||
lprintf(loglevel, "==============================================");
|
||||
}
|
||||
|
||||
for (i = 0; vs[i].str != NULL; i++) {
|
||||
if (loglevel < 0) {
|
||||
if (vs[i].val < 256)
|
||||
printf(" %d\t0x%02x\t%s\n", vs[i].val, vs[i].val, vs[i].str);
|
||||
else
|
||||
printf(" %d\t0x%04x\t%s\n", vs[i].val, vs[i].val, vs[i].str);
|
||||
} else {
|
||||
if (vs[i].val < 256)
|
||||
lprintf(loglevel, " %d\t0x%02x\t%s", vs[i].val, vs[i].val, vs[i].str);
|
||||
else
|
||||
lprintf(loglevel, " %d\t0x%04x\t%s", vs[i].val, vs[i].val, vs[i].str);
|
||||
}
|
||||
}
|
||||
|
||||
if (loglevel < 0)
|
||||
printf("\n");
|
||||
else
|
||||
lprintf(loglevel, "");
|
||||
}
|
||||
|
||||
/* print_valstr_2col - print value string list in two columns to log or stdout
|
||||
*
|
||||
* @vs: value string list to print
|
||||
* @title: name of this value string list
|
||||
* @loglevel: what log level to print, -1 for stdout
|
||||
*/
|
||||
void
|
||||
print_valstr_2col(const struct valstr * vs, const char * title, int loglevel)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (vs == NULL)
|
||||
return;
|
||||
|
||||
if (title != NULL) {
|
||||
if (loglevel < 0)
|
||||
printf("\n%s:\n\n");
|
||||
else
|
||||
lprintf(loglevel, "\n%s:\n", title);
|
||||
}
|
||||
|
||||
for (i = 0; vs[i].str != NULL; i++) {
|
||||
if (vs[i+1].str == NULL) {
|
||||
/* last one */
|
||||
if (loglevel < 0) {
|
||||
printf(" %4d %-32s\n", vs[i].val, vs[i].str);
|
||||
} else {
|
||||
lprintf(loglevel, " %4d %-32s\n", vs[i].val, vs[i].str);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (loglevel < 0) {
|
||||
printf(" %4d %-32s %4d %-32s\n",
|
||||
vs[i].val, vs[i].str, vs[i+1].val, vs[i+1].str);
|
||||
} else {
|
||||
lprintf(loglevel, " %4d %-32s %4d %-32s\n",
|
||||
vs[i].val, vs[i].str, vs[i+1].val, vs[i+1].str);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
if (loglevel < 0)
|
||||
printf("\n");
|
||||
else
|
||||
lprintf(loglevel, "");
|
||||
}
|
||||
|
||||
/* ipmi_csum - calculate an ipmi checksum
|
||||
@ -227,3 +333,66 @@ ipmi_open_file(const char * file, int rw)
|
||||
return fp;
|
||||
}
|
||||
|
||||
void
|
||||
ipmi_start_daemon(void)
|
||||
{
|
||||
pid_t pid;
|
||||
int fd;
|
||||
#ifdef SIGHUP
|
||||
sigset_t sighup;
|
||||
#endif
|
||||
|
||||
/* if we are started from init no need to become daemon */
|
||||
if (getppid() == 1)
|
||||
return;
|
||||
|
||||
#ifdef SIGHUP
|
||||
sigemptyset(&sighup);
|
||||
sigaddset(&sighup, SIGHUP);
|
||||
if (sigprocmask(SIG_UNBLOCK, &sighup, NULL) < 0)
|
||||
fprintf(stderr, "ERROR: could not unblock SIGHUP signal\n");
|
||||
signal(SIGHUP, SIG_IGN);
|
||||
#endif
|
||||
#ifdef SIGTTOU
|
||||
signal(SIGTTOU, SIG_IGN);
|
||||
#endif
|
||||
#ifdef SIGTTIN
|
||||
signal(SIGTTIN, SIG_IGN);
|
||||
#endif
|
||||
#ifdef SIGQUIT
|
||||
signal(SIGQUIT, SIG_IGN);
|
||||
#endif
|
||||
#ifdef SIGTSTP
|
||||
signal(SIGTSTP, SIG_IGN);
|
||||
#endif
|
||||
|
||||
pid = (pid_t) fork();
|
||||
if (pid < 0 || pid > 0)
|
||||
exit(0);
|
||||
|
||||
#if defined(SIGTSTP) && defined(TIOCNOTTY)
|
||||
if (setpgid(0, getpid()) == -1)
|
||||
exit(1);
|
||||
if ((fd = open(_PATH_TTY, O_RDWR)) >= 0) {
|
||||
ioctl(fd, TIOCNOTTY, NULL);
|
||||
close(fd);
|
||||
}
|
||||
#else
|
||||
if (setpgrp() == -1)
|
||||
exit(1);
|
||||
pid = (pid_t) fork();
|
||||
if (pid < 0 || pid > 0)
|
||||
exit(0);
|
||||
#endif
|
||||
|
||||
chdir("/");
|
||||
umask(0);
|
||||
|
||||
for (fd=0; fd<64; fd++)
|
||||
close(fd);
|
||||
|
||||
open("/dev/null", O_RDWR);
|
||||
dup(0);
|
||||
dup(0);
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/*
|
||||
/* -*-mode: C; indent-tabs-mode: t; -*-
|
||||
* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -37,6 +37,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
@ -54,6 +55,9 @@
|
||||
#include <ipmitool/ipmi_strings.h>
|
||||
#include <ipmitool/ipmi_constants.h>
|
||||
|
||||
extern int csv_output;
|
||||
extern int verbose;
|
||||
|
||||
void printf_channel_usage (void);
|
||||
|
||||
/**
|
||||
@ -189,6 +193,7 @@ ipmi_get_channel_info(struct ipmi_intf * intf, uint8_t channel)
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
uint8_t rqdata[2];
|
||||
uint8_t medium;
|
||||
struct get_channel_info_rsp channel_info;
|
||||
struct get_channel_access_rsp channel_access;
|
||||
|
||||
@ -245,6 +250,12 @@ ipmi_get_channel_info(struct ipmi_intf * intf, uint8_t channel)
|
||||
channel_info.vendor_id[2] << 16);
|
||||
|
||||
|
||||
/* only proceed if this is LAN channel */
|
||||
medium = ipmi_get_channel_medium(intf, channel);
|
||||
if (medium != IPMI_CHANNEL_MEDIUM_LAN &&
|
||||
medium != IPMI_CHANNEL_MEDIUM_LAN_OTHER) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
rqdata[0] = channel & 0xf;
|
||||
@ -353,8 +364,6 @@ ipmi_get_user_access(struct ipmi_intf * intf, uint8_t channel, uint8_t userid)
|
||||
struct get_user_access_rsp user_access;
|
||||
int curr_uid, max_uid = 0, init = 1;
|
||||
|
||||
ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN);
|
||||
|
||||
curr_uid = userid ? : 1;
|
||||
|
||||
memset(&req1, 0, sizeof(req1));
|
||||
@ -441,8 +450,6 @@ ipmi_set_user_access(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
struct set_user_access_data set_access;
|
||||
int i;
|
||||
|
||||
ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN);
|
||||
|
||||
if ((argc < 3) || (strncmp(argv[0], "help", 4) == 0)) {
|
||||
printf_channel_usage();
|
||||
return 0;
|
||||
@ -475,6 +482,7 @@ ipmi_set_user_access(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
|
||||
memcpy(&user_access, rsp->data, sizeof(struct get_user_access_rsp));
|
||||
|
||||
memset(&set_access, 0, sizeof(set_access));
|
||||
set_access.change_bits = 1;
|
||||
set_access.callin_callback = user_access.callin_callback;
|
||||
set_access.link_auth = user_access.link_auth;
|
||||
@ -526,6 +534,204 @@ ipmi_set_user_access(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static const char *
|
||||
iana_string(uint32_t iana)
|
||||
{
|
||||
static char s[10];
|
||||
|
||||
if (iana)
|
||||
{
|
||||
sprintf(s, "%06x", iana);
|
||||
return s;
|
||||
}
|
||||
else
|
||||
return "N/A";
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
ipmi_get_channel_cipher_suites(struct ipmi_intf * intf,
|
||||
const char * payload_type,
|
||||
uint8_t channel)
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
|
||||
uint8_t oem_record;
|
||||
uint8_t rqdata[3];
|
||||
uint32_t iana;
|
||||
uint8_t auth_alg, integrity_alg, crypt_alg;
|
||||
uint8_t cipher_suite_id;
|
||||
uint8_t list_index = 0;
|
||||
uint8_t cipher_suite_data[1024]; // 0x40 sets * 16 bytes per set
|
||||
uint16_t offset = 0;
|
||||
uint16_t cipher_suite_data_length = 0; // how much was returned, total
|
||||
|
||||
memset(cipher_suite_data, 0, sizeof(cipher_suite_data));
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.msg.netfn = IPMI_NETFN_APP; // 0x06
|
||||
req.msg.cmd = IPMI_GET_CHANNEL_CIPHER_SUITES; // 0x54
|
||||
req.msg.data = rqdata;
|
||||
req.msg.data_len = 3;
|
||||
|
||||
rqdata[0] = channel;
|
||||
rqdata[1] = ((strncmp(payload_type, "ipmi", 4) == 0)? 0: 1);
|
||||
rqdata[2] = 0x80; // Always ask for cipher suite format
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (rsp == NULL) {
|
||||
lprintf(LOG_ERR, "Unable to Get Channel Cipher Suites");
|
||||
return -1;
|
||||
}
|
||||
if (rsp->ccode > 0) {
|
||||
lprintf(LOG_ERR, "Get Channel Cipher Suites failed: %s",
|
||||
val2str(rsp->ccode, completion_code_vals));
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// Grab the returned channel number once. We assume it's the same
|
||||
// in future calls.
|
||||
if (rsp->data_len >= 1)
|
||||
channel = rsp->data[0];
|
||||
|
||||
|
||||
while ((rsp->data_len > 1) && (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);
|
||||
offset += rsp->data_len - 1;
|
||||
|
||||
//
|
||||
// Increment our list for the next call
|
||||
//
|
||||
++list_index;
|
||||
rqdata[2] = (rqdata[2] & 0x80) + list_index;
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (rsp == NULL) {
|
||||
lprintf(LOG_ERR, "Unable to Get Channel Cipher Suites");
|
||||
return -1;
|
||||
}
|
||||
if (rsp->ccode > 0) {
|
||||
lprintf(LOG_ERR, "Get Channel Cipher Suites failed: %s",
|
||||
val2str(rsp->ccode, completion_code_vals));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// We can chomp on all our data now.
|
||||
//
|
||||
cipher_suite_data_length = offset;
|
||||
offset = 0;
|
||||
|
||||
if (! csv_output)
|
||||
printf("ID IANA Auth Alg Integrity Alg Confidentiality Alg\n");
|
||||
|
||||
while (offset < cipher_suite_data_length)
|
||||
{
|
||||
if (cipher_suite_data[offset++] == 0xC0)
|
||||
{
|
||||
oem_record = 0; // standard type
|
||||
iana = 0;
|
||||
|
||||
// Verify that we have at least a full record left
|
||||
if ((cipher_suite_data_length - offset) < 4) // id + 3 algs
|
||||
{
|
||||
lprintf(LOG_ERR, "Incomplete data record in cipher suite data");
|
||||
return -1;
|
||||
}
|
||||
|
||||
cipher_suite_id = cipher_suite_data[offset++];
|
||||
|
||||
}
|
||||
else if (cipher_suite_data[offset++] == 0xC1)
|
||||
{
|
||||
oem_record = 1; // OEM record type
|
||||
|
||||
// Verify that we have at least a full record left
|
||||
if ((cipher_suite_data_length - offset) < 4) // id + iana + 3 algs
|
||||
{
|
||||
lprintf(LOG_ERR, "Incomplete data record in cipher suite data");
|
||||
return -1;
|
||||
}
|
||||
|
||||
cipher_suite_id = cipher_suite_data[offset++];
|
||||
|
||||
//
|
||||
// Grab the IANA
|
||||
//
|
||||
iana =
|
||||
cipher_suite_data[offset] |
|
||||
(cipher_suite_data[offset + 1] << 8) |
|
||||
(cipher_suite_data[offset + 2] << 16);
|
||||
offset += 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
lprintf(LOG_ERR, "Bad start of record byte in cipher suite data");
|
||||
return -1;
|
||||
}
|
||||
|
||||
//
|
||||
// Grab the algorithms for this cipher suite. I guess we can't be
|
||||
// sure of what order they'll come in. Also, I suppose we default
|
||||
// to the NONE algorithm if one were absent. This part of the spec is
|
||||
// poorly written -- I have read the errata document. For now, I'm only
|
||||
// allowing one algorithm per type (auth, integrity, crypt) because I
|
||||
// don't I understand how it could be otherwise.
|
||||
//
|
||||
auth_alg = IPMI_AUTH_RAKP_NONE;
|
||||
integrity_alg = IPMI_INTEGRITY_NONE;
|
||||
crypt_alg = IPMI_CRYPT_NONE;
|
||||
|
||||
while (((cipher_suite_data[offset] & 0xC0) != 0xC0) &&
|
||||
((cipher_suite_data_length - offset) > 0))
|
||||
{
|
||||
switch (cipher_suite_data[offset] & 0xC0)
|
||||
{
|
||||
case 0x00:
|
||||
// Authentication algorithm specifier
|
||||
auth_alg = cipher_suite_data[offset++] & 0x3F;
|
||||
break;
|
||||
case 0x40:
|
||||
// Interity algorithm specifier
|
||||
integrity_alg = cipher_suite_data[offset++] & 0x3F;
|
||||
break;
|
||||
case 0x80:
|
||||
// Confidentiality algorithm specifier
|
||||
crypt_alg = cipher_suite_data[offset++] & 0x3F;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// We have everything we need to spit out a cipher suite record
|
||||
//
|
||||
printf((csv_output? "%d,%s,%s,%s,%s\n" :
|
||||
"%-4d %-7s %-15s %-15s %-15s\n"),
|
||||
cipher_suite_id,
|
||||
iana_string(iana),
|
||||
val2str(auth_alg, ipmi_auth_algorithms),
|
||||
val2str(integrity_alg, ipmi_integrity_algorithms),
|
||||
val2str(crypt_alg, ipmi_encryption_algorithms));
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint8_t
|
||||
ipmi_get_channel_medium(struct ipmi_intf * intf, uint8_t channel)
|
||||
{
|
||||
@ -545,9 +751,11 @@ ipmi_get_channel_medium(struct ipmi_intf * intf, uint8_t channel)
|
||||
return -1;
|
||||
}
|
||||
if (rsp->ccode > 0) {
|
||||
lprintf(LOG_ERR, "Get Channel Info command failed: %s",
|
||||
if (rsp->ccode == 0xcc)
|
||||
return IPMI_CHANNEL_MEDIUM_RESERVED;
|
||||
lprintf(LOG_INFO, "Get Channel Info command failed: %s",
|
||||
val2str(rsp->ccode, completion_code_vals));
|
||||
return -1;
|
||||
return IPMI_CHANNEL_MEDIUM_RESERVED;
|
||||
}
|
||||
|
||||
memcpy(&info, rsp->data, sizeof(struct get_channel_info_rsp));
|
||||
@ -571,7 +779,8 @@ printf_channel_usage()
|
||||
lprintf(LOG_NOTICE, " getaccess <channel number> [user id]");
|
||||
lprintf(LOG_NOTICE, " setaccess <channel number> "
|
||||
"<user id> [callin=on|off] [ipmi=on|off] [link=on|off] [privilege=level]");
|
||||
lprintf(LOG_NOTICE, " info [channel number]\n");
|
||||
lprintf(LOG_NOTICE, " info [channel number]");
|
||||
lprintf(LOG_NOTICE, " getciphers <ipmi | sol> [channel]\n");
|
||||
lprintf(LOG_NOTICE, "Possible privilege levels are:");
|
||||
lprintf(LOG_NOTICE, " 1 Callback level");
|
||||
lprintf(LOG_NOTICE, " 2 User level");
|
||||
@ -627,6 +836,23 @@ ipmi_channel_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
retval = ipmi_get_channel_info(intf, ch);
|
||||
}
|
||||
}
|
||||
|
||||
// it channel getciphers <ipmi | sol> [channel]
|
||||
else if (strncmp(argv[0], "getciphers", 10) == 0)
|
||||
{
|
||||
if ((argc < 2) || (argc > 3) ||
|
||||
(strncmp(argv[1], "ipmi", 4) && strncmp(argv[1], "sol", 3)))
|
||||
printf_channel_usage();
|
||||
else
|
||||
{
|
||||
uint8_t ch = 0xe;
|
||||
if (argc == 4)
|
||||
ch = (uint8_t)strtol(argv[2], NULL, 0);
|
||||
retval = ipmi_get_channel_cipher_suites(intf,
|
||||
argv[1], // ipmi | sol
|
||||
ch);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Invalid CHANNEL command: %s\n", argv[0]);
|
||||
|
@ -42,11 +42,12 @@
|
||||
#include <ipmitool/ipmi.h>
|
||||
#include <ipmitool/log.h>
|
||||
#include <ipmitool/ipmi_intf.h>
|
||||
#include <ipmitool/ipmi_strings.h>
|
||||
#include <ipmitool/ipmi_chassis.h>
|
||||
|
||||
extern int verbose;
|
||||
|
||||
static int
|
||||
int
|
||||
ipmi_chassis_power_status(struct ipmi_intf * intf)
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
@ -68,29 +69,28 @@ ipmi_chassis_power_status(struct ipmi_intf * intf)
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("Chassis Power is %s\n", (rsp->data[0] & 0x1) ? "on" : "off");
|
||||
return rsp->data[0] & 1;
|
||||
}
|
||||
|
||||
static int
|
||||
ipmi_chassis_print_power_status(struct ipmi_intf * intf)
|
||||
{
|
||||
int ps = ipmi_chassis_power_status(intf);
|
||||
|
||||
if (ps < 0)
|
||||
return -1;
|
||||
|
||||
printf("Chassis Power is %s\n", ps ? "on" : "off");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct valstr ipmi_chassis_power_control_vals[] = {
|
||||
{ 0x00, "Down/Off" },
|
||||
{ 0x01, "Up/On" },
|
||||
{ 0x02, "Cycle" },
|
||||
{ 0x03, "Reset" },
|
||||
{ 0x04, "Pulse" },
|
||||
{ 0x05, "Soft" },
|
||||
{ 0x00, NULL },
|
||||
};
|
||||
|
||||
static int
|
||||
int
|
||||
ipmi_chassis_power_control(struct ipmi_intf * intf, uint8_t ctl)
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
|
||||
ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN);
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.msg.netfn = IPMI_NETFN_CHASSIS;
|
||||
req.msg.cmd = 0x2;
|
||||
@ -113,8 +113,10 @@ ipmi_chassis_power_control(struct ipmi_intf * intf, uint8_t ctl)
|
||||
printf("Chassis Power Control: %s\n",
|
||||
val2str(ctl, ipmi_chassis_power_control_vals));
|
||||
|
||||
#if 0 /* this can cause sessions to hang around after power commands */
|
||||
/* sessions often get lost when changing chassis power */
|
||||
intf->abort = 1;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -130,8 +132,6 @@ ipmi_chassis_identify(struct ipmi_intf * intf, char * arg)
|
||||
uint8_t force_on;
|
||||
} identify_data;
|
||||
|
||||
ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN);
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.msg.netfn = IPMI_NETFN_CHASSIS;
|
||||
req.msg.cmd = 0x4;
|
||||
@ -213,6 +213,8 @@ ipmi_chassis_poh(struct ipmi_intf * intf)
|
||||
|
||||
printf("POH Counter : %li hours total (%li days, %li hours)\n",
|
||||
(long)count, (long)(count / 24), (long)(count % 24));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -358,6 +360,75 @@ ipmi_chassis_status(struct ipmi_intf * intf)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
ipmi_chassis_selftest(struct ipmi_intf * intf)
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.msg.netfn = IPMI_NETFN_APP;
|
||||
req.msg.cmd = 0x4;
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (rsp == NULL) {
|
||||
lprintf(LOG_ERR, "Error sending Get Self Test command");
|
||||
return -1;
|
||||
}
|
||||
if (rsp->ccode > 0) {
|
||||
lprintf(LOG_ERR, "Error sending Get Self Test command: %s",
|
||||
val2str(rsp->ccode, completion_code_vals));
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("Self Test Results : ");
|
||||
switch (rsp->data[0]) {
|
||||
case 0x55:
|
||||
printf("passed\n");
|
||||
break;
|
||||
|
||||
case 0x56:
|
||||
printf("not implemented\n");
|
||||
break;
|
||||
|
||||
case 0x57:
|
||||
{
|
||||
int i;
|
||||
const struct valstr broken_dev_vals[] = {
|
||||
{ 0, "firmware corrupted" },
|
||||
{ 1, "boot block corrupted" },
|
||||
{ 2, "FRU Internal Use Area corrupted" },
|
||||
{ 3, "SDR Repository empty" },
|
||||
{ 4, "IPMB not responding" },
|
||||
{ 5, "cannot access BMC FRU" },
|
||||
{ 6, "cannot access SDR Repository" },
|
||||
{ 7, "cannot access SEL Device" },
|
||||
{ 0xff, NULL },
|
||||
};
|
||||
printf("device error\n");
|
||||
for (i=0; i<8; i++) {
|
||||
if (rsp->data[1] & (1<<i)) {
|
||||
printf(" [%s]\n",
|
||||
val2str(i, broken_dev_vals));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x58:
|
||||
printf("Fatal hardware error: %02xh\n", rsp->data[1]);
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("Device-specific failure %02xh:%02xh\n",
|
||||
rsp->data[0], rsp->data[1]);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ipmi_chassis_set_bootparam(struct ipmi_intf * intf, uint8_t param, uint8_t * data, int len)
|
||||
{
|
||||
@ -365,8 +436,6 @@ ipmi_chassis_set_bootparam(struct ipmi_intf * intf, uint8_t param, uint8_t * dat
|
||||
struct ipmi_rq req;
|
||||
uint8_t msg_data[16];
|
||||
|
||||
ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN);
|
||||
|
||||
memset(msg_data, 0, 16);
|
||||
msg_data[0] = param & 0x7f;
|
||||
memcpy(msg_data+1, data, len);
|
||||
@ -388,7 +457,7 @@ ipmi_chassis_set_bootparam(struct ipmi_intf * intf, uint8_t param, uint8_t * dat
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("Chassis Set Boot Parameter %d to %s\n", param, data);
|
||||
lprintf(LOG_DEBUG, "Chassis Set Boot Parameter %d to %s", param, buf2str(data, len));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -435,41 +504,57 @@ ipmi_chassis_get_bootparam(struct ipmi_intf * intf, char * arg)
|
||||
}
|
||||
|
||||
static int
|
||||
ipmi_chassis_set_bootflag(struct ipmi_intf * intf, char * arg)
|
||||
ipmi_chassis_set_bootdev(struct ipmi_intf * intf, char * arg, int clearcmos)
|
||||
{
|
||||
uint8_t flags[5];
|
||||
int rc = 0;
|
||||
|
||||
ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN);
|
||||
|
||||
if (arg == NULL) {
|
||||
lprintf(LOG_ERR, "No bootflag argument supplied");
|
||||
memset(flags, 0, 5);
|
||||
flags[0] = 0x01;
|
||||
flags[1] = 0x01;
|
||||
rc = ipmi_chassis_set_bootparam(intf, 4, flags, 2);
|
||||
if (rc < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (strncmp(arg, "force_pxe", 9) == 0)
|
||||
memset(flags, 0, 5);
|
||||
if (arg == NULL)
|
||||
flags[1] = 0x00;
|
||||
else if (strncmp(arg, "none", 4) == 0)
|
||||
flags[1] = 0x00;
|
||||
else if (strncmp(arg, "pxe", 3) == 0 ||
|
||||
strncmp(arg, "force_pxe", 9) == 0)
|
||||
flags[1] = 0x04;
|
||||
else if (strncmp(arg, "force_disk", 10) == 0)
|
||||
else if (strncmp(arg, "disk", 4) == 0 ||
|
||||
strncmp(arg, "force_disk", 10) == 0)
|
||||
flags[1] = 0x08;
|
||||
else if (strncmp(arg, "force_diag", 10) == 0)
|
||||
else if (strncmp(arg, "safe", 4) == 0 ||
|
||||
strncmp(arg, "force_safe", 10) == 0)
|
||||
flags[1] = 0x0c;
|
||||
else if (strncmp(arg, "diag", 4) == 0 ||
|
||||
strncmp(arg, "force_diag", 10) == 0)
|
||||
flags[1] = 0x10;
|
||||
else if (strncmp(arg, "force_cdrom", 11) == 0)
|
||||
else if (strncmp(arg, "cdrom", 5) == 0 ||
|
||||
strncmp(arg, "force_cdrom", 11) == 0)
|
||||
flags[1] = 0x14;
|
||||
else if (strncmp(arg, "force_floppy", 12) == 0)
|
||||
else if (strncmp(arg, "floppy", 6) == 0 ||
|
||||
strncmp(arg, "force_floppy", 12) == 0)
|
||||
flags[1] = 0x3c;
|
||||
else if (strncmp(arg, "bios", 4) == 0 ||
|
||||
strncmp(arg, "force_bios", 10) == 0)
|
||||
flags[1] = 0x18;
|
||||
else {
|
||||
lprintf(LOG_ERR, "Invalid bootflag: %s", arg);
|
||||
lprintf(LOG_ERR, "Invalid argument: %s", arg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
flags[0] = 0x80; /* set flag valid bit */
|
||||
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] = 0x08; /* don't automatically clear boot flag valid bit in 60 seconds */
|
||||
rc = ipmi_chassis_set_bootparam(intf, 3, flags, 1);
|
||||
}
|
||||
|
||||
if (rc == 0)
|
||||
printf("Set Boot Device to %s\n", arg);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -479,8 +564,6 @@ ipmi_chassis_power_policy(struct ipmi_intf * intf, uint8_t policy)
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
|
||||
ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN);
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.msg.netfn = IPMI_NETFN_CHASSIS;
|
||||
req.msg.cmd = 0x6;
|
||||
@ -527,17 +610,55 @@ ipmi_chassis_power_policy(struct ipmi_intf * intf, uint8_t policy)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ipmi_power_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
{
|
||||
int rc = 0;
|
||||
uint8_t ctl = 0;
|
||||
|
||||
if ((argc < 1) || (strncmp(argv[0], "help", 4) == 0)) {
|
||||
lprintf(LOG_NOTICE, "chassis power Commands: status, on, off, cycle, reset, diag, soft");
|
||||
return 0;
|
||||
}
|
||||
if (strncmp(argv[0], "status", 6) == 0) {
|
||||
rc = ipmi_chassis_print_power_status(intf);
|
||||
return rc;
|
||||
}
|
||||
if ((strncmp(argv[0], "up", 2) == 0) || (strncmp(argv[0], "on", 2) == 0))
|
||||
ctl = IPMI_CHASSIS_CTL_POWER_UP;
|
||||
else if ((strncmp(argv[0], "down", 4) == 0) || (strncmp(argv[0], "off", 3) == 0))
|
||||
ctl = IPMI_CHASSIS_CTL_POWER_DOWN;
|
||||
else if (strncmp(argv[0], "cycle", 5) == 0)
|
||||
ctl = IPMI_CHASSIS_CTL_POWER_CYCLE;
|
||||
else if (strncmp(argv[0], "reset", 5) == 0)
|
||||
ctl = IPMI_CHASSIS_CTL_HARD_RESET;
|
||||
else if (strncmp(argv[0], "diag", 4) == 0)
|
||||
ctl = IPMI_CHASSIS_CTL_PULSE_DIAG;
|
||||
else if ((strncmp(argv[0], "acpi", 4) == 0) || (strncmp(argv[0], "soft", 4) == 0))
|
||||
ctl = IPMI_CHASSIS_CTL_ACPI_SOFT;
|
||||
else {
|
||||
lprintf(LOG_ERR, "Invalid chassis power command: %s", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = ipmi_chassis_power_control(intf, ctl);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
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");
|
||||
lprintf(LOG_NOTICE, "Chassis Commands: status, power, identify, policy, restart_cause, poh, bootdev, selftest");
|
||||
}
|
||||
else if (strncmp(argv[0], "status", 6) == 0) {
|
||||
rc = ipmi_chassis_status(intf);
|
||||
}
|
||||
else if (strncmp(argv[0], "selftest", 8) == 0) {
|
||||
rc = ipmi_chassis_selftest(intf);
|
||||
}
|
||||
else if (strncmp(argv[0], "power", 5) == 0) {
|
||||
uint8_t ctl = 0;
|
||||
|
||||
@ -546,7 +667,7 @@ ipmi_chassis_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
return 0;
|
||||
}
|
||||
if (strncmp(argv[1], "status", 6) == 0) {
|
||||
rc = ipmi_chassis_power_status(intf);
|
||||
rc = ipmi_chassis_print_power_status(intf);
|
||||
return rc;
|
||||
}
|
||||
if ((strncmp(argv[1], "up", 2) == 0) || (strncmp(argv[1], "on", 2) == 0))
|
||||
@ -611,9 +732,16 @@ ipmi_chassis_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
rc = ipmi_chassis_power_policy(intf, ctl);
|
||||
}
|
||||
}
|
||||
else if (strncmp(argv[0], "bootparam", 7) == 0) {
|
||||
else if (strncmp(argv[0], "bootparam", 9) == 0) {
|
||||
if ((argc < 3) || (strncmp(argv[1], "help", 4) == 0)) {
|
||||
lprintf(LOG_NOTICE, "bootparam get|set <option> [value ...]");
|
||||
lprintf(LOG_NOTICE, "bootparam get <param #>");
|
||||
lprintf(LOG_NOTICE, "bootparam set bootflag <flag>");
|
||||
lprintf(LOG_NOTICE, " force_pxe : Force PXE boot");
|
||||
lprintf(LOG_NOTICE, " force_disk : Force boot from default Hard-drive");
|
||||
lprintf(LOG_NOTICE, " force_safe : Force boot from default Hard-drive, request Safe Mode");
|
||||
lprintf(LOG_NOTICE, " force_diag : Force boot from Diagnostic Partition");
|
||||
lprintf(LOG_NOTICE, " force_cdrom : Force boot from CD/DVD");
|
||||
lprintf(LOG_NOTICE, " force_bios : Force boot into BIOS Setup");
|
||||
}
|
||||
else {
|
||||
if (strncmp(argv[1], "get", 3) == 0) {
|
||||
@ -624,7 +752,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_bootflag(intf, argv[3]);
|
||||
rc = ipmi_chassis_set_bootdev(intf, argv[3], 0);
|
||||
else
|
||||
lprintf(LOG_NOTICE, "bootparam set <option> [value ...]");
|
||||
}
|
||||
@ -633,6 +761,29 @@ ipmi_chassis_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
lprintf(LOG_NOTICE, "bootparam get|set <option> [value ...]");
|
||||
}
|
||||
}
|
||||
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, " none : Do not change boot device order");
|
||||
lprintf(LOG_NOTICE, " pxe : Force PXE boot");
|
||||
lprintf(LOG_NOTICE, " disk : Force boot from default Hard-drive");
|
||||
lprintf(LOG_NOTICE, " safe : Force boot from default Hard-drive, request Safe Mode");
|
||||
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");
|
||||
} else {
|
||||
if (argc < 3)
|
||||
rc = ipmi_chassis_set_bootdev(intf, argv[1], 0);
|
||||
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);
|
||||
}
|
||||
else
|
||||
rc = ipmi_chassis_set_bootdev(intf, argv[1], 0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
lprintf(LOG_ERR, "Invalid Chassis command: %s", argv[0]);
|
||||
return -1;
|
||||
|
@ -53,17 +53,42 @@
|
||||
#include <ipmitool/ipmi_sel.h>
|
||||
#include <ipmitool/ipmi_strings.h>
|
||||
#include <ipmitool/ipmi_channel.h>
|
||||
#include <ipmitool/ipmi_event.h>
|
||||
#include <ipmitool/ipmi_sdr.h>
|
||||
|
||||
|
||||
static int
|
||||
ipmi_send_platform_event(struct ipmi_intf * intf, int num)
|
||||
ipmi_event_msg_print(struct ipmi_intf * intf, struct platform_event_msg * pmsg)
|
||||
{
|
||||
struct sel_event_record sel_event;
|
||||
|
||||
memset(&sel_event, 0, sizeof(struct sel_event_record));
|
||||
|
||||
sel_event.record_id = 0;
|
||||
sel_event.sel_type.standard_type.gen_id = 2;
|
||||
|
||||
sel_event.sel_type.standard_type.evm_rev = pmsg->evm_rev;
|
||||
sel_event.sel_type.standard_type.sensor_type = pmsg->sensor_type;
|
||||
sel_event.sel_type.standard_type.sensor_num = pmsg->sensor_num;
|
||||
sel_event.sel_type.standard_type.event_type = pmsg->event_type;
|
||||
sel_event.sel_type.standard_type.event_dir = pmsg->event_dir;
|
||||
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
|
||||
ipmi_sel_print_extended_entry(intf, &sel_event);
|
||||
}
|
||||
|
||||
static int
|
||||
ipmi_send_platform_event(struct ipmi_intf * intf, struct platform_event_msg * emsg)
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
uint8_t rqdata[8];
|
||||
uint8_t chmed;
|
||||
int p = 0;
|
||||
|
||||
ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN);
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
memset(rqdata, 0, 8);
|
||||
@ -71,53 +96,20 @@ ipmi_send_platform_event(struct ipmi_intf * intf, int num)
|
||||
req.msg.netfn = IPMI_NETFN_SE;
|
||||
req.msg.cmd = 0x02;
|
||||
req.msg.data = rqdata;
|
||||
req.msg.data_len = 7;
|
||||
|
||||
chmed = ipmi_current_channel_medium(intf);
|
||||
if (chmed == IPMI_CHANNEL_MEDIUM_SYSTEM) {
|
||||
/* system interface, need extra generator ID */
|
||||
req.msg.data_len = 8;
|
||||
rqdata[p++] = 0x20;
|
||||
rqdata[0] = 0x20;
|
||||
memcpy(rqdata+1, emsg, sizeof(struct platform_event_msg));
|
||||
}
|
||||
else {
|
||||
req.msg.data_len = 7;
|
||||
memcpy(rqdata, emsg, sizeof(struct platform_event_msg));
|
||||
}
|
||||
|
||||
/* IPMB/LAN/etc */
|
||||
switch (num) {
|
||||
case 1: /* temperature */
|
||||
printf("Sending SAMPLE event: Temperature - "
|
||||
"Upper Critical - Going High\n");
|
||||
rqdata[p++] = 0x04; /* EvMRev */
|
||||
rqdata[p++] = 0x01; /* Sensor Type */
|
||||
rqdata[p++] = 0x30; /* Sensor # */
|
||||
rqdata[p++] = 0x01; /* Event Dir / Event Type */
|
||||
rqdata[p++] = 0x59; /* Event Data 1 */
|
||||
rqdata[p++] = 0x00; /* Event Data 2 */
|
||||
rqdata[p++] = 0x00; /* Event Data 3 */
|
||||
break;
|
||||
case 2: /* voltage error */
|
||||
printf("Sending SAMPLE event: Voltage Threshold - "
|
||||
"Lower Critical - Going Low\n");
|
||||
rqdata[p++] = 0x04; /* EvMRev */
|
||||
rqdata[p++] = 0x02; /* Sensor Type */
|
||||
rqdata[p++] = 0x60; /* Sensor # */
|
||||
rqdata[p++] = 0x01; /* Event Dir / Event Type */
|
||||
rqdata[p++] = 0x52; /* Event Data 1 */
|
||||
rqdata[p++] = 0x00; /* Event Data 2 */
|
||||
rqdata[p++] = 0x00; /* Event Data 3 */
|
||||
break;
|
||||
case 3: /* correctable ECC */
|
||||
printf("Sending SAMPLE event: Memory - Correctable ECC\n");
|
||||
rqdata[p++] = 0x04; /* EvMRev */
|
||||
rqdata[p++] = 0x0c; /* Sensor Type */
|
||||
rqdata[p++] = 0x53; /* Sensor # */
|
||||
rqdata[p++] = 0x6f; /* Event Dir / Event Type */
|
||||
rqdata[p++] = 0x00; /* Event Data 1 */
|
||||
rqdata[p++] = 0x00; /* Event Data 2 */
|
||||
rqdata[p++] = 0x00; /* Event Data 3 */
|
||||
break;
|
||||
default:
|
||||
lprintf(LOG_ERR, "Invalid event number: %d", num);
|
||||
return -1;
|
||||
}
|
||||
ipmi_event_msg_print(intf, emsg);
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (rsp == NULL) {
|
||||
@ -133,6 +125,358 @@ ipmi_send_platform_event(struct ipmi_intf * intf, int num)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define EVENT_THRESH_STATE_LNC_LO 0
|
||||
#define EVENT_THRESH_STATE_LNC_HI 1
|
||||
#define EVENT_THRESH_STATE_LCR_LO 2
|
||||
#define EVENT_THRESH_STATE_LCR_HI 3
|
||||
#define EVENT_THRESH_STATE_LNR_LO 4
|
||||
#define EVENT_THRESH_STATE_LNR_HI 5
|
||||
#define EVENT_THRESH_STATE_UNC_LO 6
|
||||
#define EVENT_THRESH_STATE_UNC_HI 7
|
||||
#define EVENT_THRESH_STATE_UCR_LO 8
|
||||
#define EVENT_THRESH_STATE_UCR_HI 9
|
||||
#define EVENT_THRESH_STATE_UNR_LO 10
|
||||
#define EVENT_THRESH_STATE_UNR_HI 11
|
||||
|
||||
static const struct valstr ipmi_event_thresh_lo[] = {
|
||||
{ EVENT_THRESH_STATE_LNC_LO, "lnc" },
|
||||
{ EVENT_THRESH_STATE_LCR_LO, "lcr" },
|
||||
{ EVENT_THRESH_STATE_LNR_LO, "lnr" },
|
||||
{ EVENT_THRESH_STATE_UNC_LO, "unc" },
|
||||
{ EVENT_THRESH_STATE_UCR_LO, "ucr" },
|
||||
{ EVENT_THRESH_STATE_UNR_LO, "unr" },
|
||||
{ 0, NULL },
|
||||
};
|
||||
static const struct valstr ipmi_event_thresh_hi[] = {
|
||||
{ EVENT_THRESH_STATE_LNC_HI, "lnc" },
|
||||
{ EVENT_THRESH_STATE_LCR_HI, "lcr" },
|
||||
{ EVENT_THRESH_STATE_LNR_HI, "lnr" },
|
||||
{ EVENT_THRESH_STATE_UNC_HI, "unc" },
|
||||
{ EVENT_THRESH_STATE_UCR_HI, "ucr" },
|
||||
{ EVENT_THRESH_STATE_UNR_HI, "unr" },
|
||||
{ 0, NULL },
|
||||
};
|
||||
|
||||
static int
|
||||
ipmi_send_platform_event_num(struct ipmi_intf * intf, int num)
|
||||
{
|
||||
struct platform_event_msg emsg;
|
||||
|
||||
memset(&emsg, 0, sizeof(struct platform_event_msg));
|
||||
|
||||
/* IPMB/LAN/etc */
|
||||
switch (num) {
|
||||
case 1: /* temperature */
|
||||
printf("Sending SAMPLE event: Temperature - "
|
||||
"Upper Critical - Going High\n");
|
||||
emsg.evm_rev = 0x04;
|
||||
emsg.sensor_type = 0x01;
|
||||
emsg.sensor_num = 0x30;
|
||||
emsg.event_dir = EVENT_DIR_ASSERT;
|
||||
emsg.event_type = 0x01;
|
||||
emsg.event_data[0] = EVENT_THRESH_STATE_UCR_HI;
|
||||
emsg.event_data[1] = 0xff;
|
||||
emsg.event_data[2] = 0xff;
|
||||
break;
|
||||
case 2: /* voltage error */
|
||||
printf("Sending SAMPLE event: Voltage Threshold - "
|
||||
"Lower Critical - Going Low\n");
|
||||
emsg.evm_rev = 0x04;
|
||||
emsg.sensor_type = 0x02;
|
||||
emsg.sensor_num = 0x60;
|
||||
emsg.event_dir = EVENT_DIR_ASSERT;
|
||||
emsg.event_type = 0x01;
|
||||
emsg.event_data[0] = EVENT_THRESH_STATE_LCR_LO;
|
||||
emsg.event_data[1] = 0xff;
|
||||
emsg.event_data[2] = 0xff;
|
||||
break;
|
||||
case 3: /* correctable ECC */
|
||||
printf("Sending SAMPLE event: Memory - Correctable ECC\n");
|
||||
emsg.evm_rev = 0x04;
|
||||
emsg.sensor_type = 0x0c;
|
||||
emsg.sensor_num = 0x53;
|
||||
emsg.event_dir = EVENT_DIR_ASSERT;
|
||||
emsg.event_type = 0x6f;
|
||||
emsg.event_data[0] = 0x00;
|
||||
emsg.event_data[1] = 0xff;
|
||||
emsg.event_data[2] = 0xff;
|
||||
break;
|
||||
default:
|
||||
lprintf(LOG_ERR, "Invalid event number: %d", num);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ipmi_send_platform_event(intf, &emsg);
|
||||
}
|
||||
|
||||
static int
|
||||
ipmi_event_find_offset(uint8_t code,
|
||||
struct ipmi_event_sensor_types * evt,
|
||||
char * desc)
|
||||
{
|
||||
if (desc == NULL || code == 0)
|
||||
return 0x00;
|
||||
|
||||
while (evt->type) {
|
||||
if (evt->code == code && evt->desc != NULL &&
|
||||
strncasecmp(desc, evt->desc, __maxlen(desc, evt->desc)) == 0)
|
||||
return evt->offset;
|
||||
evt++;
|
||||
}
|
||||
|
||||
lprintf(LOG_WARN, "Unable to find matching event offset for '%s'", desc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void
|
||||
print_sensor_states(uint8_t sensor_type, uint8_t event_type)
|
||||
{
|
||||
printf("Sensor States: \n ");
|
||||
ipmi_sdr_print_discrete_state_mini("\n ", sensor_type,
|
||||
event_type, 0xff, 0xff);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
ipmi_event_fromsensor(struct ipmi_intf * intf, char * id, char * state, char * evdir)
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
struct sdr_record_list * sdr;
|
||||
struct platform_event_msg emsg;
|
||||
int off;
|
||||
|
||||
if (id == NULL) {
|
||||
lprintf(LOG_ERR, "No sensor ID supplied");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&emsg, 0, sizeof(struct platform_event_msg));
|
||||
emsg.evm_rev = 0x04;
|
||||
|
||||
if (evdir == NULL)
|
||||
emsg.event_dir = EVENT_DIR_ASSERT;
|
||||
else if (strncasecmp(evdir, "assert", 6) == 0)
|
||||
emsg.event_dir = EVENT_DIR_ASSERT;
|
||||
else if (strncasecmp(evdir, "deassert", 8) == 0)
|
||||
emsg.event_dir = EVENT_DIR_DEASSERT;
|
||||
else {
|
||||
lprintf(LOG_ERR, "Invalid event direction %s. Must be 'assert' or 'deassert'", evdir);
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("Finding sensor %s... ", id);
|
||||
sdr = ipmi_sdr_find_sdr_byid(intf, id);
|
||||
if (sdr == NULL) {
|
||||
printf("not found!\n");
|
||||
return -1;
|
||||
}
|
||||
printf("ok\n");
|
||||
|
||||
switch (sdr->type)
|
||||
{
|
||||
case SDR_RECORD_TYPE_FULL_SENSOR:
|
||||
|
||||
emsg.sensor_type = sdr->record.full->sensor.type;
|
||||
emsg.sensor_num = sdr->record.full->keys.sensor_num;
|
||||
emsg.event_type = sdr->record.full->event_type;
|
||||
break;
|
||||
|
||||
case SDR_RECORD_TYPE_COMPACT_SENSOR:
|
||||
|
||||
emsg.sensor_type = sdr->record.compact->sensor.type;
|
||||
emsg.sensor_num = sdr->record.compact->keys.sensor_num;
|
||||
emsg.event_type = sdr->record.compact->event_type;
|
||||
break;
|
||||
|
||||
default:
|
||||
lprintf(LOG_ERR, "Unknown sensor type for id '%s'", id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
emsg.event_data[1] = 0xff;
|
||||
emsg.event_data[2] = 0xff;
|
||||
|
||||
switch (emsg.event_type)
|
||||
{
|
||||
/*
|
||||
* Threshold Class
|
||||
*/
|
||||
case 1:
|
||||
{
|
||||
int dir = 0;
|
||||
int hilo = 0;
|
||||
off = 1;
|
||||
|
||||
if (state == NULL || strncasecmp(state, "list", 4) == 0) {
|
||||
printf("Sensor States:\n");
|
||||
printf(" lnr : Lower Non-Recoverable \n");
|
||||
printf(" lcr : Lower Critical\n");
|
||||
printf(" lnc : Lower Non-Critical\n");
|
||||
printf(" unc : Upper Non-Critical\n");
|
||||
printf(" ucr : Upper Critical\n");
|
||||
printf(" unr : Upper Non-Recoverable\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (0 != strncasecmp(state, "lnr", 3) &&
|
||||
0 != strncasecmp(state, "lcr", 3) &&
|
||||
0 != strncasecmp(state, "lnc", 3) &&
|
||||
0 != strncasecmp(state, "unc", 3) &&
|
||||
0 != strncasecmp(state, "ucr", 3) &&
|
||||
0 != strncasecmp(state, "unr", 3))
|
||||
{
|
||||
lprintf(LOG_ERR, "Invalid threshold identifier %s", state);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (state[0] == 'u')
|
||||
hilo = 1;
|
||||
else
|
||||
hilo = 0;
|
||||
|
||||
if (emsg.event_dir == EVENT_DIR_ASSERT)
|
||||
dir = hilo;
|
||||
else
|
||||
dir = !hilo;
|
||||
|
||||
if ((emsg.event_dir == EVENT_DIR_ASSERT && hilo == 1) ||
|
||||
(emsg.event_dir == EVENT_DIR_DEASSERT && hilo == 0))
|
||||
emsg.event_data[0] = (uint8_t)(str2val(state, ipmi_event_thresh_hi) & 0xf);
|
||||
else if ((emsg.event_dir == EVENT_DIR_ASSERT && hilo == 0) ||
|
||||
(emsg.event_dir == EVENT_DIR_DEASSERT && hilo == 1))
|
||||
emsg.event_data[0] = (uint8_t)(str2val(state, ipmi_event_thresh_lo) & 0xf);
|
||||
else {
|
||||
lprintf(LOG_ERR, "Invalid Event\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
rsp = ipmi_sdr_get_sensor_thresholds(intf, emsg.sensor_num);
|
||||
|
||||
if (rsp != NULL && rsp->ccode == 0) {
|
||||
|
||||
/* threshold reading */
|
||||
emsg.event_data[2] = rsp->data[(emsg.event_data[0] / 2) + 1];
|
||||
|
||||
rsp = ipmi_sdr_get_sensor_hysteresis(intf, emsg.sensor_num);
|
||||
if (rsp != NULL && rsp->ccode == 0)
|
||||
off = dir ? rsp->data[0] : rsp->data[1];
|
||||
if (off <= 0)
|
||||
off = 1;
|
||||
|
||||
/* trigger reading */
|
||||
if (dir) {
|
||||
if ((emsg.event_data[2] + off) > 0xff)
|
||||
emsg.event_data[1] = 0xff;
|
||||
else
|
||||
emsg.event_data[1] = emsg.event_data[2] + off;
|
||||
}
|
||||
else {
|
||||
if ((emsg.event_data[2] - off) < 0)
|
||||
emsg.event_data[1] = 0;
|
||||
else
|
||||
emsg.event_data[1] = emsg.event_data[2] - off;
|
||||
}
|
||||
|
||||
/* trigger in byte 2, threshold in byte 3 */
|
||||
emsg.event_data[0] |= 0x50;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
/*
|
||||
* Digital Discrete
|
||||
*/
|
||||
case 3: case 4: case 5: case 6: case 8: case 9:
|
||||
{
|
||||
int x;
|
||||
const char * digi_on[] = { "present", "assert", "limit",
|
||||
"fail", "yes", "on", "up" };
|
||||
const char * digi_off[] = { "absent", "deassert", "nolimit",
|
||||
"nofail", "no", "off", "down" };
|
||||
/*
|
||||
* print list of available states for this sensor
|
||||
*/
|
||||
if (state == NULL || strncasecmp(state, "list", 4) == 0) {
|
||||
print_sensor_states(emsg.sensor_type, emsg.event_type);
|
||||
printf("Sensor State Shortcuts:\n");
|
||||
for (x = 0; x < sizeof(digi_on)/sizeof(*digi_on); x++) {
|
||||
printf(" %-9s %-9s\n", digi_on[x], digi_off[x]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
off = 0;
|
||||
for (x = 0; x < sizeof(digi_on)/sizeof(*digi_on); x++) {
|
||||
if (strncasecmp(state, digi_on[x], strlen(digi_on[x])) == 0) {
|
||||
emsg.event_data[0] = 1;
|
||||
off = 1;
|
||||
break;
|
||||
}
|
||||
else if (strncasecmp(state, digi_off[x], strlen(digi_off[x])) == 0) {
|
||||
emsg.event_data[0] = 0;
|
||||
off = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (off == 0) {
|
||||
off = ipmi_event_find_offset(
|
||||
emsg.event_type, generic_event_types, state);
|
||||
if (off < 0)
|
||||
return -1;
|
||||
emsg.event_data[0] = off;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
/*
|
||||
* Generic Discrete
|
||||
*/
|
||||
case 2: case 7: case 10: case 11: case 12:
|
||||
{
|
||||
/*
|
||||
* print list of available states for this sensor
|
||||
*/
|
||||
if (state == NULL || strncasecmp(state, "list", 4) == 0) {
|
||||
print_sensor_states(emsg.sensor_type, emsg.event_type);
|
||||
return 0;
|
||||
}
|
||||
off = ipmi_event_find_offset(
|
||||
emsg.event_type, generic_event_types, state);
|
||||
if (off < 0)
|
||||
return -1;
|
||||
emsg.event_data[0] = off;
|
||||
}
|
||||
break;
|
||||
|
||||
/*
|
||||
* Sensor-Specific Discrete
|
||||
*/
|
||||
case 0x6f:
|
||||
{
|
||||
/*
|
||||
* print list of available states for this sensor
|
||||
*/
|
||||
if (state == NULL || strncasecmp(state, "list", 4) == 0) {
|
||||
print_sensor_states(emsg.sensor_type, emsg.event_type);
|
||||
return 0;
|
||||
}
|
||||
off = ipmi_event_find_offset(
|
||||
emsg.sensor_type, sensor_specific_types, state);
|
||||
if (off < 0)
|
||||
return -1;
|
||||
emsg.event_data[0] = off;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
return ipmi_send_platform_event(intf, &emsg);
|
||||
}
|
||||
|
||||
static int
|
||||
ipmi_event_fromfile(struct ipmi_intf * intf, char * file)
|
||||
{
|
||||
@ -150,9 +494,6 @@ ipmi_event_fromfile(struct ipmi_intf * intf, char * file)
|
||||
if (file == NULL)
|
||||
return -1;
|
||||
|
||||
/* must be admin privilege to do this */
|
||||
ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN);
|
||||
|
||||
memset(rqdata, 0, 8);
|
||||
|
||||
/* setup Platform Event Message command */
|
||||
@ -173,7 +514,7 @@ ipmi_event_fromfile(struct ipmi_intf * intf, char * file)
|
||||
if (fp == NULL)
|
||||
return -1;
|
||||
|
||||
while (feof(fp) != 0) {
|
||||
while (feof(fp) == 0) {
|
||||
if (fgets(buf, 1024, fp) == NULL)
|
||||
continue;
|
||||
|
||||
@ -215,19 +556,19 @@ ipmi_event_fromfile(struct ipmi_intf * intf, char * file)
|
||||
|
||||
memset(&sel_event, 0, sizeof(struct sel_event_record));
|
||||
sel_event.record_id = 0;
|
||||
sel_event.gen_id = 2;
|
||||
sel_event.sel_type.standard_type.gen_id = 2;
|
||||
|
||||
j = (chmed == IPMI_CHANNEL_MEDIUM_SYSTEM) ? 1 : 0;
|
||||
sel_event.evm_rev = rqdata[j++];
|
||||
sel_event.sensor_type = rqdata[j++];
|
||||
sel_event.sensor_num = rqdata[j++];
|
||||
sel_event.event_type = rqdata[j] & 0x7f;
|
||||
sel_event.event_dir = (rqdata[j++] & 0x80) >> 7;
|
||||
sel_event.event_data[0] = rqdata[j++];
|
||||
sel_event.event_data[1] = rqdata[j++];
|
||||
sel_event.event_data[2] = rqdata[j++];
|
||||
sel_event.sel_type.standard_type.evm_rev = rqdata[j++];
|
||||
sel_event.sel_type.standard_type.sensor_type = rqdata[j++];
|
||||
sel_event.sel_type.standard_type.sensor_num = rqdata[j++];
|
||||
sel_event.sel_type.standard_type.event_type = rqdata[j] & 0x7f;
|
||||
sel_event.sel_type.standard_type.event_dir = (rqdata[j++] & 0x80) >> 7;
|
||||
sel_event.sel_type.standard_type.event_data[0] = rqdata[j++];
|
||||
sel_event.sel_type.standard_type.event_data[1] = rqdata[j++];
|
||||
sel_event.sel_type.standard_type.event_data[2] = rqdata[j++];
|
||||
|
||||
ipmi_sel_print_std_entry(&sel_event);
|
||||
ipmi_sel_print_std_entry(intf, &sel_event);
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (rsp == NULL) {
|
||||
@ -245,33 +586,56 @@ ipmi_event_fromfile(struct ipmi_intf * intf, char * file)
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
ipmi_event_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
static void
|
||||
ipmi_event_usage(void)
|
||||
{
|
||||
uint8_t c;
|
||||
int rc = 0;
|
||||
|
||||
if (argc == 0 || strncmp(argv[0], "help", 4) == 0) {
|
||||
lprintf(LOG_NOTICE, "");
|
||||
lprintf(LOG_NOTICE, "usage: event <num>");
|
||||
lprintf(LOG_NOTICE, " Send generic test events");
|
||||
lprintf(LOG_NOTICE, " 1 : Temperature - Upper Critical - Going High");
|
||||
lprintf(LOG_NOTICE, " 2 : Voltage Threshold - Lower Critical - Going Low");
|
||||
lprintf(LOG_NOTICE, " 3 : Memory - Correctable ECC");
|
||||
lprintf(LOG_NOTICE, "");
|
||||
lprintf(LOG_NOTICE, "usage: event file <filename>");
|
||||
lprintf(LOG_NOTICE, " Will read list of events from file");
|
||||
lprintf(LOG_NOTICE, " Read and generate events from file");
|
||||
lprintf(LOG_NOTICE, " Use the 'sel save' command to generate from SEL");
|
||||
lprintf(LOG_NOTICE, "");
|
||||
lprintf(LOG_NOTICE, "usage: event <sensorid> <state> [event_dir]");
|
||||
lprintf(LOG_NOTICE, " sensorid : Sensor ID to use for event data");
|
||||
lprintf(LOG_NOTICE, " state : Sensor state, use 'list' to see possible states for sensor");
|
||||
lprintf(LOG_NOTICE, " event_dir : assert, deassert [default=assert]");
|
||||
lprintf(LOG_NOTICE, "");
|
||||
}
|
||||
|
||||
int
|
||||
ipmi_event_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (argc == 0 || strncmp(argv[0], "help", 4) == 0) {
|
||||
ipmi_event_usage();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strncmp(argv[0], "file", 4) == 0) {
|
||||
if (argc < 2) {
|
||||
lprintf(LOG_NOTICE, "usage: event file <filename>\n");
|
||||
rc = -1;
|
||||
} else {
|
||||
rc = ipmi_event_fromfile(intf, argv[1]);
|
||||
ipmi_event_usage();
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
c = (uint8_t)strtol(argv[0], NULL, 0);
|
||||
rc = ipmi_send_platform_event(intf, c);
|
||||
return ipmi_event_fromfile(intf, argv[1]);
|
||||
}
|
||||
if (strlen(argv[0]) == 1) {
|
||||
switch (argv[0][0]) {
|
||||
case '1': return ipmi_send_platform_event_num(intf, 1);
|
||||
case '2': return ipmi_send_platform_event_num(intf, 2);
|
||||
case '3': return ipmi_send_platform_event_num(intf, 3);
|
||||
}
|
||||
}
|
||||
if (argc < 2)
|
||||
rc = ipmi_event_fromsensor(intf, argv[0], NULL, NULL);
|
||||
else if (argc < 3)
|
||||
rc = ipmi_event_fromsensor(intf, argv[0], argv[1], NULL);
|
||||
else
|
||||
rc = ipmi_event_fromsensor(intf, argv[0], argv[1], argv[2]);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
1138
ipmitool/lib/ipmi_fwum.c
Normal file
1138
ipmitool/lib/ipmi_fwum.c
Normal file
File diff suppressed because it is too large
Load Diff
195
ipmitool/lib/ipmi_isol.c
Normal file
195
ipmitool/lib/ipmi_isol.c
Normal file
@ -0,0 +1,195 @@
|
||||
/*
|
||||
* 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 <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <ipmitool/helper.h>
|
||||
#include <ipmitool/log.h>
|
||||
#include <ipmitool/ipmi.h>
|
||||
#include <ipmitool/ipmi_strings.h>
|
||||
#include <ipmitool/ipmi_intf.h>
|
||||
#include <ipmitool/ipmi_isol.h>
|
||||
|
||||
const struct valstr ipmi_isol_baud_vals[] = {
|
||||
{ ISOL_BAUD_RATE_9600, "9600" },
|
||||
{ ISOL_BAUD_RATE_19200, "19200" },
|
||||
{ ISOL_BAUD_RATE_38400, "38400" },
|
||||
{ ISOL_BAUD_RATE_57600, "57600" },
|
||||
{ ISOL_BAUD_RATE_115200, "115200" },
|
||||
{ 0x00, NULL }
|
||||
};
|
||||
|
||||
extern int verbose;
|
||||
|
||||
static int ipmi_isol_setup(struct ipmi_intf * intf, char baudsetting)
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
unsigned char data[6];
|
||||
|
||||
/* TEST FOR AVAILABILITY */
|
||||
|
||||
memset(data, 0, 6);
|
||||
data[0] = 0x00;
|
||||
data[1] = ISOL_ENABLE_PARAM;
|
||||
data[2] = ISOL_ENABLE_FLAG;
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.msg.netfn = IPMI_NETFN_ISOL;
|
||||
req.msg.cmd = SET_ISOL_CONFIG;
|
||||
req.msg.data = data;
|
||||
req.msg.data_len = 3;
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (rsp == NULL) {
|
||||
lprintf(LOG_ERR, "Error in Set ISOL Config Command");
|
||||
return -1;
|
||||
}
|
||||
if (rsp->ccode == 0xc1) {
|
||||
lprintf(LOG_ERR, "IPMI v1.5 Serial Over Lan (ISOL) not supported!");
|
||||
return -1;
|
||||
}
|
||||
if (rsp->ccode > 0) {
|
||||
lprintf(LOG_ERR, "Error in Set ISOL Config Command: %s",
|
||||
val2str(rsp->ccode, completion_code_vals));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* GET ISOL CONFIG */
|
||||
|
||||
memset(data, 0, 6);
|
||||
data[0] = 0x00;
|
||||
data[1] = ISOL_AUTHENTICATION_PARAM;
|
||||
data[2] = 0x00; /* block */
|
||||
data[3] = 0x00; /* selector */
|
||||
req.msg.cmd = GET_ISOL_CONFIG;
|
||||
req.msg.data_len = 4;
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (rsp == NULL) {
|
||||
lprintf(LOG_ERR, "Error in Get ISOL Config Command");
|
||||
return -1;
|
||||
}
|
||||
if (rsp->ccode > 0) {
|
||||
lprintf(LOG_ERR, "Error in Get ISOL Config Command: %s",
|
||||
val2str(rsp->ccode, completion_code_vals));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (verbose > 1)
|
||||
printbuf(rsp->data, rsp->data_len, "ISOL Config");
|
||||
|
||||
/* SET ISOL CONFIG - AUTHENTICATION */
|
||||
|
||||
memset(data, 0, 6);
|
||||
data[0] = 0x00;
|
||||
data[1] = ISOL_AUTHENTICATION_PARAM;
|
||||
data[2] = ISOL_PRIVILEGE_LEVEL_USER | (rsp->data[1] & 0x80);
|
||||
req.msg.cmd = SET_ISOL_CONFIG;
|
||||
req.msg.data_len = 3;
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (rsp == NULL) {
|
||||
lprintf(LOG_ERR, "Error in Set ISOL Config (Authentication) Command");
|
||||
return -1;
|
||||
}
|
||||
if (rsp->ccode > 0) {
|
||||
lprintf(LOG_ERR, "Error in Set ISOL Config (Authentication) Command: %s",
|
||||
val2str(rsp->ccode, completion_code_vals));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* SET ISOL CONFIG - BAUD RATE */
|
||||
|
||||
memset(data, 0, 6);
|
||||
data[0] = 0x00;
|
||||
data[1] = ISOL_BAUD_RATE_PARAM;
|
||||
data[2] = baudsetting;
|
||||
req.msg.cmd = SET_ISOL_CONFIG;
|
||||
req.msg.data_len = 3;
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (rsp == NULL) {
|
||||
lprintf(LOG_ERR, "Error in Set ISOL Config (Baud Rate) Command");
|
||||
return -1;
|
||||
}
|
||||
if (rsp->ccode > 0) {
|
||||
lprintf(LOG_ERR, "Error in Set ISOL Config (Baud Rate) Command: %s",
|
||||
val2str(rsp->ccode, completion_code_vals));
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("Set ISOL Baud Rate to %s\n",
|
||||
val2str(baudsetting, ipmi_isol_baud_vals));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ipmi_isol_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (argc < 2 || strncmp(argv[0], "help", 4) == 0) {
|
||||
lprintf(LOG_NOTICE, "ISOL Commands: setup <baud>");
|
||||
lprintf(LOG_NOTICE, "ISOL Baud Rates: 9600, 19200, 38400, 57600, 115200");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strncmp(argv[0], "setup", 5) == 0) {
|
||||
if (strncmp(argv[1], "9600", 4) == 0) {
|
||||
ret = ipmi_isol_setup(intf, ISOL_BAUD_RATE_9600);
|
||||
}
|
||||
else if (strncmp(argv[1], "19200", 5) == 0) {
|
||||
ret = ipmi_isol_setup(intf, ISOL_BAUD_RATE_19200);
|
||||
}
|
||||
else if (strncmp(argv[1], "38400", 5) == 0) {
|
||||
ret = ipmi_isol_setup(intf, ISOL_BAUD_RATE_38400);
|
||||
}
|
||||
else if (strncmp(argv[1], "57600", 5) == 0) {
|
||||
ret = ipmi_isol_setup(intf, ISOL_BAUD_RATE_57600);
|
||||
}
|
||||
else if (strncmp(argv[1], "115200", 6) == 0) {
|
||||
ret = ipmi_isol_setup(intf, ISOL_BAUD_RATE_115200);
|
||||
}
|
||||
else {
|
||||
lprintf(LOG_ERR, "ISOL - Unsupported baud rate: %s", argv[1]);
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
616
ipmitool/lib/ipmi_main.c
Normal file
616
ipmitool/lib/ipmi_main.c
Normal file
@ -0,0 +1,616 @@
|
||||
/*
|
||||
* 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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <ipmitool/helper.h>
|
||||
#include <ipmitool/log.h>
|
||||
#include <ipmitool/ipmi.h>
|
||||
#include <ipmitool/ipmi_intf.h>
|
||||
#include <ipmitool/ipmi_session.h>
|
||||
#include <ipmitool/ipmi_sdr.h>
|
||||
#include <ipmitool/ipmi_sel.h>
|
||||
#include <ipmitool/ipmi_fru.h>
|
||||
#include <ipmitool/ipmi_sol.h>
|
||||
#include <ipmitool/ipmi_isol.h>
|
||||
#include <ipmitool/ipmi_lanp.h>
|
||||
#include <ipmitool/ipmi_chassis.h>
|
||||
#include <ipmitool/ipmi_mc.h>
|
||||
#include <ipmitool/ipmi_sensor.h>
|
||||
#include <ipmitool/ipmi_channel.h>
|
||||
#include <ipmitool/ipmi_session.h>
|
||||
#include <ipmitool/ipmi_event.h>
|
||||
#include <ipmitool/ipmi_user.h>
|
||||
#include <ipmitool/ipmi_raw.h>
|
||||
#include <ipmitool/ipmi_pef.h>
|
||||
#include <ipmitool/ipmi_oem.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#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:"
|
||||
#else
|
||||
# define OPTION_STRING "I:hVvcH:f:U:p:S:"
|
||||
#endif
|
||||
|
||||
extern int verbose;
|
||||
extern int csv_output;
|
||||
extern const struct valstr ipmi_privlvl_vals[];
|
||||
extern const struct valstr ipmi_authtype_session_vals[];
|
||||
|
||||
/* defined in ipmishell.c */
|
||||
#ifdef HAVE_READLINE
|
||||
extern int ipmi_shell_main(struct ipmi_intf * intf, int argc, char ** argv);
|
||||
#endif
|
||||
extern int ipmi_set_main(struct ipmi_intf * intf, int argc, char ** argv);
|
||||
extern int ipmi_exec_main(struct ipmi_intf * intf, int argc, char ** argv);
|
||||
|
||||
|
||||
/* ipmi_password_file_read - Open file and read password from it
|
||||
*
|
||||
* @filename: file name to read from
|
||||
*
|
||||
* returns pointer to allocated buffer containing password
|
||||
* (caller is expected to free when finished)
|
||||
* returns NULL on error
|
||||
*/
|
||||
static char *
|
||||
ipmi_password_file_read(char * filename)
|
||||
{
|
||||
FILE * fp;
|
||||
char * pass = NULL;
|
||||
int l;
|
||||
|
||||
pass = malloc(16);
|
||||
if (pass == NULL) {
|
||||
lprintf(LOG_ERR, "ipmitool: malloc failure");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fp = ipmi_open_file_read((const char *)filename);
|
||||
if (fp == NULL) {
|
||||
lprintf(LOG_ERR, "Unable to open password file %s",
|
||||
filename);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* read in id */
|
||||
if (fgets(pass, 16, fp) == NULL) {
|
||||
lprintf(LOG_ERR, "Unable to read password from file %s",
|
||||
filename);
|
||||
fclose(fp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* remove trailing whitespace */
|
||||
l = strcspn(pass, " \r\n\t");
|
||||
if (l > 0) {
|
||||
pass[l] = '\0';
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
return pass;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Print all the commands in the above table to stderr
|
||||
* used for help text on command line and shell
|
||||
*/
|
||||
void
|
||||
ipmi_cmd_print(struct ipmi_cmd * cmdlist)
|
||||
{
|
||||
struct ipmi_cmd * cmd;
|
||||
int hdr = 0;
|
||||
|
||||
if (cmdlist == NULL)
|
||||
return;
|
||||
for (cmd=cmdlist; cmd->func != NULL; cmd++) {
|
||||
if (cmd->desc == NULL)
|
||||
continue;
|
||||
if (hdr == 0) {
|
||||
lprintf(LOG_NOTICE, "Commands:");
|
||||
hdr = 1;
|
||||
}
|
||||
lprintf(LOG_NOTICE, "\t%-12s %s", cmd->name, cmd->desc);
|
||||
}
|
||||
lprintf(LOG_NOTICE, "");
|
||||
}
|
||||
|
||||
/* ipmi_cmd_run - run a command from list based on parameters
|
||||
* called from main()
|
||||
*
|
||||
* 1. iterate through ipmi_cmd_list matching on name
|
||||
* 2. call func() for that command
|
||||
*
|
||||
* @intf: ipmi interface
|
||||
* @name: command name
|
||||
* @argc: command argument count
|
||||
* @argv: command argument list
|
||||
*
|
||||
* returns value from func() of that commnad if found
|
||||
* returns -1 if command is not found
|
||||
*/
|
||||
int
|
||||
ipmi_cmd_run(struct ipmi_intf * intf, char * name, int argc, char ** argv)
|
||||
{
|
||||
struct ipmi_cmd * cmd = intf->cmdlist;
|
||||
|
||||
/* hook to run a default command if nothing specified */
|
||||
if (name == NULL) {
|
||||
if (cmd->func == NULL || cmd->name == NULL)
|
||||
return -1;
|
||||
else if (strncmp(cmd->name, "default", 7) == 0)
|
||||
return cmd->func(intf, 0, NULL);
|
||||
else {
|
||||
lprintf(LOG_ERR, "No command provided!");
|
||||
ipmi_cmd_print(intf->cmdlist);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
for (cmd=intf->cmdlist; cmd->func != NULL; cmd++) {
|
||||
if (strncmp(name, cmd->name, __maxlen(cmd->name, name)) == 0)
|
||||
break;
|
||||
}
|
||||
if (cmd->func == NULL) {
|
||||
cmd = intf->cmdlist;
|
||||
if (strncmp(cmd->name, "default", 7) == 0)
|
||||
return cmd->func(intf, argc+1, argv-1);
|
||||
lprintf(LOG_ERR, "Invalid command: %s", name);
|
||||
ipmi_cmd_print(intf->cmdlist);
|
||||
return -1;
|
||||
}
|
||||
return cmd->func(intf, argc, argv);
|
||||
}
|
||||
|
||||
static void
|
||||
ipmi_option_usage(const char * progname, struct ipmi_cmd * cmdlist, struct ipmi_intf_support * intflist)
|
||||
{
|
||||
lprintf(LOG_NOTICE, "%s version %s\n", progname, VERSION);
|
||||
lprintf(LOG_NOTICE, "usage: %s [options...] <command>\n", progname);
|
||||
lprintf(LOG_NOTICE, " -h This help");
|
||||
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, " -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]");
|
||||
lprintf(LOG_NOTICE, " -U username Remote session username");
|
||||
lprintf(LOG_NOTICE, " -f file Read remote session password from file");
|
||||
lprintf(LOG_NOTICE, " -S sdr Use local file for remote SDR cache");
|
||||
#ifdef ENABLE_ALL_OPTIONS
|
||||
lprintf(LOG_NOTICE, " -a Prompt for remote password");
|
||||
lprintf(LOG_NOTICE, " -e char Set SOL escape character");
|
||||
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, " -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");
|
||||
lprintf(LOG_NOTICE, " -m address Set local IPMB address");
|
||||
lprintf(LOG_NOTICE, " -b channel Set destination channel for bridged request");
|
||||
lprintf(LOG_NOTICE, " -l lun Set destination lun for raw commands");
|
||||
lprintf(LOG_NOTICE, " -t address Bridge request to remote target address");
|
||||
lprintf(LOG_NOTICE, " -o oemtype Setup for OEM (use 'list' to see available OEM types)");
|
||||
#endif
|
||||
lprintf(LOG_NOTICE, "");
|
||||
|
||||
ipmi_intf_print(intflist);
|
||||
|
||||
if (cmdlist != NULL)
|
||||
ipmi_cmd_print(cmdlist);
|
||||
}
|
||||
|
||||
|
||||
/* ipmi_parse_options - helper function to handle parsing command line options
|
||||
*
|
||||
* @argc: count of options
|
||||
* @argv: list of options
|
||||
* @cmdlist: list of supported commands
|
||||
* @intflist: list of supported interfaces
|
||||
*
|
||||
* returns 0 on success
|
||||
* returns -1 on error
|
||||
*/
|
||||
int
|
||||
ipmi_main(int argc, char ** argv,
|
||||
struct ipmi_cmd * cmdlist,
|
||||
struct ipmi_intf_support * intflist)
|
||||
{
|
||||
struct ipmi_intf * intf = NULL;
|
||||
struct ipmi_intf_support * sup;
|
||||
int privlvl = 0;
|
||||
uint8_t target_addr = 0;
|
||||
uint8_t target_channel = 0;
|
||||
uint8_t target_lun = 0;
|
||||
uint8_t my_addr = 0;
|
||||
int authtype = -1;
|
||||
char * tmp = NULL;
|
||||
char * hostname = NULL;
|
||||
char * username = NULL;
|
||||
char * password = NULL;
|
||||
char * intfname = NULL;
|
||||
char * progname = NULL;
|
||||
char * oemtype = NULL;
|
||||
char * sdrcache = NULL;
|
||||
char * kgkey = NULL;
|
||||
int port = 0;
|
||||
int cipher_suite_id = 3; /* See table 22-19 of the IPMIv2 spec */
|
||||
int argflag, i, found;
|
||||
int rc = -1;
|
||||
char sol_escape_char = SOL_ESCAPE_CHARACTER_DEFAULT;
|
||||
|
||||
/* save program name */
|
||||
progname = strrchr(argv[0], '/');
|
||||
progname = ((progname == NULL) ? argv[0] : progname+1);
|
||||
|
||||
while ((argflag = getopt(argc, (char **)argv, OPTION_STRING)) != -1)
|
||||
{
|
||||
switch (argflag) {
|
||||
case 'I':
|
||||
intfname = strdup(optarg);
|
||||
if (intfname == NULL) {
|
||||
lprintf(LOG_ERR, "%s: malloc failure", progname);
|
||||
goto out_free;
|
||||
}
|
||||
if (intflist != NULL) {
|
||||
found = 0;
|
||||
for (sup=intflist; sup->name != NULL; sup++) {
|
||||
if (strncmp(sup->name, intfname, strlen(intfname)) == 0 &&
|
||||
strncmp(sup->name, intfname, strlen(sup->name)) == 0 &&
|
||||
sup->supported == 1)
|
||||
found = 1;
|
||||
}
|
||||
if (!found) {
|
||||
lprintf(LOG_ERR, "Interface %s not supported", intfname);
|
||||
goto out_free;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'h':
|
||||
ipmi_option_usage(progname, cmdlist, intflist);
|
||||
rc = 0;
|
||||
goto out_free;
|
||||
break;
|
||||
case 'V':
|
||||
printf("%s version %s\n", progname, VERSION);
|
||||
rc = 0;
|
||||
goto out_free;
|
||||
break;
|
||||
case 'p':
|
||||
port = atoi(optarg);
|
||||
break;
|
||||
case 'C':
|
||||
cipher_suite_id = atoi(optarg);
|
||||
break;
|
||||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
case 'c':
|
||||
csv_output = 1;
|
||||
break;
|
||||
case 'H':
|
||||
hostname = strdup(optarg);
|
||||
if (hostname == NULL) {
|
||||
lprintf(LOG_ERR, "%s: malloc failure", progname);
|
||||
goto out_free;
|
||||
}
|
||||
break;
|
||||
case 'f':
|
||||
if (password)
|
||||
free(password);
|
||||
password = ipmi_password_file_read(optarg);
|
||||
if (password == NULL)
|
||||
lprintf(LOG_ERR, "Unable to read password "
|
||||
"from file %s", optarg);
|
||||
break;
|
||||
case 'a':
|
||||
#ifdef HAVE_GETPASSPHRASE
|
||||
tmp = getpassphrase("Password: ");
|
||||
#else
|
||||
tmp = getpass("Password: ");
|
||||
#endif
|
||||
if (tmp != NULL) {
|
||||
if (password)
|
||||
free(password);
|
||||
password = strdup(tmp);
|
||||
if (password == NULL) {
|
||||
lprintf(LOG_ERR, "%s: malloc failure", progname);
|
||||
goto out_free;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'k':
|
||||
kgkey = strdup(optarg);
|
||||
if (kgkey == NULL) {
|
||||
lprintf(LOG_ERR, "%s: malloc failure", progname);
|
||||
goto out_free;
|
||||
}
|
||||
break;
|
||||
case 'U':
|
||||
username = strdup(optarg);
|
||||
if (username == NULL) {
|
||||
lprintf(LOG_ERR, "%s: malloc failure", progname);
|
||||
goto out_free;
|
||||
}
|
||||
break;
|
||||
case 'S':
|
||||
sdrcache = strdup(optarg);
|
||||
if (sdrcache == NULL) {
|
||||
lprintf(LOG_ERR, "%s: malloc failure", progname);
|
||||
goto out_free;
|
||||
}
|
||||
break;
|
||||
#ifdef ENABLE_ALL_OPTIONS
|
||||
case 'o':
|
||||
oemtype = strdup(optarg);
|
||||
if (oemtype == NULL) {
|
||||
lprintf(LOG_ERR, "%s: malloc failure", progname);
|
||||
goto out_free;
|
||||
}
|
||||
if (strncmp(oemtype, "list", 4) == 0 ||
|
||||
strncmp(oemtype, "help", 4) == 0) {
|
||||
ipmi_oem_print();
|
||||
goto out_free;
|
||||
}
|
||||
break;
|
||||
case 'g':
|
||||
/* backwards compatible oem hack */
|
||||
oemtype = strdup("intelwv2");
|
||||
break;
|
||||
case 's':
|
||||
/* backwards compatible oem hack */
|
||||
oemtype = strdup("supermicro");
|
||||
break;
|
||||
case 'P':
|
||||
if (password)
|
||||
free(password);
|
||||
password = strdup(optarg);
|
||||
if (password == NULL) {
|
||||
lprintf(LOG_ERR, "%s: malloc failure", progname);
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
/* Prevent password snooping with ps */
|
||||
i = strlen(optarg);
|
||||
memset(optarg, 'X', i);
|
||||
break;
|
||||
case 'E':
|
||||
if ((tmp = getenv("IPMITOOL_PASSWORD")))
|
||||
{
|
||||
if (password)
|
||||
free(password);
|
||||
password = strdup(tmp);
|
||||
if (password == NULL) {
|
||||
lprintf(LOG_ERR, "%s: malloc failure", progname);
|
||||
goto out_free;
|
||||
}
|
||||
}
|
||||
else if ((tmp = getenv("IPMI_PASSWORD")))
|
||||
{
|
||||
if (password)
|
||||
free(password);
|
||||
password = strdup(tmp);
|
||||
if (password == NULL) {
|
||||
lprintf(LOG_ERR, "%s: malloc failure", progname);
|
||||
goto out_free;
|
||||
}
|
||||
}
|
||||
else {
|
||||
lprintf(LOG_WARN, "Unable to read password from environment");
|
||||
}
|
||||
break;
|
||||
case 'L':
|
||||
privlvl = str2val(optarg, ipmi_privlvl_vals);
|
||||
if (privlvl == 0xFF)
|
||||
lprintf(LOG_WARN, "Invalid privilege level %s", optarg);
|
||||
break;
|
||||
case 'A':
|
||||
authtype = str2val(optarg, ipmi_authtype_session_vals);
|
||||
break;
|
||||
case 't':
|
||||
target_addr = (uint8_t)strtol(optarg, NULL, 0);
|
||||
break;
|
||||
case 'b':
|
||||
target_channel = (uint8_t)strtol(optarg, NULL, 0);
|
||||
break;
|
||||
case 'l':
|
||||
target_lun = (uint8_t)strtol(optarg, NULL, 0);
|
||||
break;
|
||||
case 'm':
|
||||
my_addr = (uint8_t)strtol(optarg, NULL, 0);
|
||||
break;
|
||||
case 'e':
|
||||
sol_escape_char = optarg[0];
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
ipmi_option_usage(progname, cmdlist, intflist);
|
||||
goto out_free;
|
||||
}
|
||||
}
|
||||
|
||||
/* check for command before doing anything */
|
||||
if (argc-optind > 0 &&
|
||||
strncmp(argv[optind], "help", 4) == 0) {
|
||||
ipmi_cmd_print(cmdlist);
|
||||
rc = 0;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the user has specified a hostname (-H option)
|
||||
* then this is a remote access session.
|
||||
*
|
||||
* If no password was specified by any other method
|
||||
* and the authtype was not explicitly set to NONE
|
||||
* then prompt the user.
|
||||
*/
|
||||
if (hostname != NULL && password == NULL &&
|
||||
(authtype != IPMI_SESSION_AUTHTYPE_NONE || authtype < 0)) {
|
||||
#ifdef HAVE_GETPASSPHRASE
|
||||
tmp = getpassphrase("Password: ");
|
||||
#else
|
||||
tmp = getpass("Password: ");
|
||||
#endif
|
||||
if (tmp != NULL) {
|
||||
password = strdup(tmp);
|
||||
if (password == NULL) {
|
||||
lprintf(LOG_ERR, "%s: malloc failure", progname);
|
||||
goto out_free;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* if no interface was specified but a
|
||||
* hostname was then use LAN by default
|
||||
* otherwise the default is hardcoded
|
||||
* to use the first entry in the list
|
||||
*/
|
||||
if (intfname == NULL && hostname != NULL) {
|
||||
intfname = strdup("lan");
|
||||
if (intfname == NULL) {
|
||||
lprintf(LOG_ERR, "%s: malloc failure", progname);
|
||||
goto out_free;
|
||||
}
|
||||
}
|
||||
|
||||
/* load interface */
|
||||
intf = ipmi_intf_load(intfname);
|
||||
if (intf == NULL) {
|
||||
lprintf(LOG_ERR, "Error loading interface %s", intfname);
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
/* setup log */
|
||||
log_init(progname, 0, verbose);
|
||||
|
||||
/* run OEM setup if found */
|
||||
if (oemtype != NULL &&
|
||||
ipmi_oem_setup(intf, oemtype) < 0) {
|
||||
lprintf(LOG_ERR, "OEM setup for \"%s\" failed", oemtype);
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
/* set session variables */
|
||||
if (hostname != NULL)
|
||||
ipmi_intf_session_set_hostname(intf, hostname);
|
||||
if (username != NULL)
|
||||
ipmi_intf_session_set_username(intf, username);
|
||||
if (password != NULL)
|
||||
ipmi_intf_session_set_password(intf, password);
|
||||
if (kgkey != NULL)
|
||||
ipmi_intf_session_set_kgkey(intf, kgkey);
|
||||
if (port > 0)
|
||||
ipmi_intf_session_set_port(intf, port);
|
||||
if (authtype >= 0)
|
||||
ipmi_intf_session_set_authtype(intf, (uint8_t)authtype);
|
||||
if (privlvl > 0)
|
||||
ipmi_intf_session_set_privlvl(intf, (uint8_t)privlvl);
|
||||
else
|
||||
ipmi_intf_session_set_privlvl(intf,
|
||||
IPMI_SESSION_PRIV_ADMIN); /* default */
|
||||
|
||||
ipmi_intf_session_set_sol_escape_char(intf, sol_escape_char);
|
||||
ipmi_intf_session_set_cipher_suite_id(intf, cipher_suite_id);
|
||||
|
||||
/* setup destination lun if given */
|
||||
intf->target_lun = target_lun ;
|
||||
|
||||
/* setup destination channel if given */
|
||||
intf->target_channel = target_channel ;
|
||||
|
||||
/* setup IPMB local and target address if given */
|
||||
intf->my_addr = my_addr ? : IPMI_BMC_SLAVE_ADDR;
|
||||
if (target_addr > 0) {
|
||||
/* need to open the interface first */
|
||||
if (intf->open != NULL)
|
||||
intf->open(intf);
|
||||
intf->target_addr = target_addr;
|
||||
/* must be admin level to do this over lan */
|
||||
ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN);
|
||||
}
|
||||
|
||||
/* parse local SDR cache if given */
|
||||
if (sdrcache != NULL) {
|
||||
ipmi_sdr_list_cache_fromfile(intf, sdrcache);
|
||||
}
|
||||
|
||||
intf->cmdlist = cmdlist;
|
||||
|
||||
/* now we finally run the command */
|
||||
if (argc-optind > 0)
|
||||
rc = ipmi_cmd_run(intf, argv[optind], argc-optind-1, &(argv[optind+1]));
|
||||
else
|
||||
rc = ipmi_cmd_run(intf, NULL, 0, NULL);
|
||||
|
||||
/* clean repository caches */
|
||||
ipmi_cleanup(intf);
|
||||
|
||||
/* call interface close function if available */
|
||||
if (intf->opened > 0 && intf->close != NULL)
|
||||
intf->close(intf);
|
||||
|
||||
out_free:
|
||||
log_halt();
|
||||
|
||||
if (intfname != NULL)
|
||||
free(intfname);
|
||||
if (hostname != NULL)
|
||||
free(hostname);
|
||||
if (username != NULL)
|
||||
free(username);
|
||||
if (password != NULL)
|
||||
free(password);
|
||||
if (oemtype != NULL)
|
||||
free(oemtype);
|
||||
|
||||
return rc;
|
||||
}
|
@ -37,9 +37,11 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <ipmitool/helper.h>
|
||||
#include <ipmitool/log.h>
|
||||
#include <ipmitool/bswap.h>
|
||||
#include <ipmitool/ipmi.h>
|
||||
#include <ipmitool/ipmi_intf.h>
|
||||
#include <ipmitool/ipmi_mc.h>
|
||||
@ -63,21 +65,23 @@ ipmi_mc_reset(struct ipmi_intf * intf, int cmd)
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
|
||||
intf->open(intf);
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.msg.netfn = IPMI_NETFN_APP;
|
||||
req.msg.cmd = cmd;
|
||||
req.msg.data_len = 0;
|
||||
|
||||
if (cmd == BMC_COLD_RESET)
|
||||
intf->noanswer = 1;
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (rsp == NULL) {
|
||||
lprintf(LOG_ERR, "Reset command failed");
|
||||
return -1;
|
||||
}
|
||||
if (rsp->ccode > 0) {
|
||||
lprintf(LOG_ERR, "Reset command failed: %s",
|
||||
val2str(rsp->ccode, completion_code_vals));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (cmd == BMC_COLD_RESET)
|
||||
intf->abort = 1;
|
||||
|
||||
printf("Sent %s reset command to MC\n",
|
||||
(cmd == BMC_WARM_RESET) ? "warm" : "cold");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -150,12 +154,13 @@ struct bitfield_data mc_enables_bf[] = {
|
||||
};
|
||||
|
||||
static void
|
||||
printf_mc_usage()
|
||||
printf_mc_usage(void)
|
||||
{
|
||||
struct bitfield_data * bf;
|
||||
printf("MC Commands:\n");
|
||||
printf(" reset <warm|cold>\n");
|
||||
printf(" info\n");
|
||||
printf(" selftest\n");
|
||||
printf(" getenables\n");
|
||||
printf(" setenables <option=on|off> ...\n");
|
||||
|
||||
@ -219,8 +224,6 @@ ipmi_mc_set_enables(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
uint8_t en;
|
||||
int i;
|
||||
|
||||
ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN);
|
||||
|
||||
if (argc < 1 || strncmp(argv[0], "help", 4) == 0) {
|
||||
printf_mc_usage();
|
||||
return 0;
|
||||
@ -345,6 +348,10 @@ ipmi_mc_get_deviceid(struct ipmi_intf * intf)
|
||||
IPM_DEV_IPMI_VERSION_MINOR(devid->ipmi_version));
|
||||
printf("Manufacturer ID : %lu\n",
|
||||
(long)IPM_DEV_MANUFACTURER_ID(devid->manufacturer_id));
|
||||
printf("Manufacturer Name : %s\n",
|
||||
val2str( (long)IPM_DEV_MANUFACTURER_ID(devid->manufacturer_id),
|
||||
ipmi_oem_info) );
|
||||
|
||||
printf("Product ID : %u (0x%02x%02x)\n",
|
||||
buf2short((uint8_t *)(devid->product_id)),
|
||||
devid->product_id[1], devid->product_id[0]);
|
||||
@ -370,6 +377,154 @@ ipmi_mc_get_deviceid(struct ipmi_intf * intf)
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct ipmi_guid {
|
||||
uint32_t time_low; /* timestamp low field */
|
||||
uint16_t time_mid; /* timestamp middle field */
|
||||
uint16_t time_hi_and_version; /* timestamp high field and version number */
|
||||
uint8_t clock_seq_hi_variant;/* clock sequence high field and variant */
|
||||
uint8_t clock_seq_low; /* clock sequence low field */
|
||||
uint8_t node[6]; /* node */
|
||||
} __attribute__((packed));
|
||||
|
||||
/* ipmi_mc_get_guid - print this MC GUID
|
||||
*
|
||||
* @intf: ipmi interface
|
||||
*
|
||||
* returns 0 on success
|
||||
* returns -1 on error
|
||||
*/
|
||||
static int
|
||||
ipmi_mc_get_guid(struct ipmi_intf * intf)
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
struct ipmi_guid guid;
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.msg.netfn = IPMI_NETFN_APP;
|
||||
req.msg.cmd = BMC_GET_GUID;
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (rsp == NULL) {
|
||||
lprintf(LOG_ERR, "Get GUID command failed");
|
||||
return -1;
|
||||
}
|
||||
if (rsp->ccode > 0) {
|
||||
lprintf(LOG_ERR, "Get GUID command failed: %s",
|
||||
val2str(rsp->ccode, completion_code_vals));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rsp->data_len == sizeof(struct ipmi_guid)) {
|
||||
uint8_t tbuf[40];
|
||||
time_t s;
|
||||
memset(tbuf, 0, 40);
|
||||
memset(&guid, 0, sizeof(struct ipmi_guid));
|
||||
memcpy(&guid, rsp->data, rsp->data_len);
|
||||
|
||||
printf("System GUID : %08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x\n",
|
||||
guid.time_low, guid.time_mid, guid.time_hi_and_version,
|
||||
guid.clock_seq_hi_variant << 8 | guid.clock_seq_low,
|
||||
guid.node[5], guid.node[4], guid.node[3],
|
||||
guid.node[2], guid.node[1], guid.node[0]);
|
||||
|
||||
s = (time_t)BSWAP_32(guid.time_low);
|
||||
strftime(tbuf, sizeof(tbuf), "%m/%d/%Y %H:%M:%S", localtime(&s));
|
||||
printf("Timestamp : %s\n", tbuf);
|
||||
}
|
||||
else {
|
||||
lprintf(LOG_ERR, "Invalid GUID length %d", rsp->data_len);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ipmi_mc_get_selftest - returns and print selftest results
|
||||
*
|
||||
* @intf: ipmi interface
|
||||
*/
|
||||
static int ipmi_mc_get_selftest(struct ipmi_intf * intf)
|
||||
{
|
||||
int rv = 0;
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
struct ipm_selftest_rsp *sft_res;
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.msg.netfn = IPMI_NETFN_APP;
|
||||
req.msg.cmd = BMC_GET_SELF_TEST;
|
||||
req.msg.data_len = 0;
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (!rsp) {
|
||||
lprintf(LOG_ERR, "No response from devices\n");
|
||||
return -1;
|
||||
}
|
||||
if (rsp->ccode) {
|
||||
lprintf(LOG_ERR, "Bad response: (%s)",
|
||||
val2str(rsp->ccode, completion_code_vals));
|
||||
return -1;
|
||||
}
|
||||
|
||||
sft_res = (struct ipm_selftest_rsp *) rsp->data;
|
||||
|
||||
if (sft_res->code == IPM_SFT_CODE_OK) {
|
||||
printf("Selftest: passed\n");
|
||||
rv = 0;
|
||||
}
|
||||
|
||||
else if (sft_res->code == IPM_SFT_CODE_NOT_IMPLEMENTED) {
|
||||
printf("Selftest: not implemented\n");
|
||||
rv = -1;
|
||||
}
|
||||
|
||||
else if (sft_res->code == IPM_SFT_CODE_DEV_CORRUPTED) {
|
||||
printf("Selftest: device corrupted\n");
|
||||
rv = -1;
|
||||
|
||||
if (sft_res->test & IPM_SELFTEST_SEL_ERROR) {
|
||||
printf(" -> SEL device not accessible\n");
|
||||
}
|
||||
if (sft_res->test & IPM_SELFTEST_SDR_ERROR) {
|
||||
printf(" -> SDR repository not accesible\n");
|
||||
}
|
||||
if (sft_res->test & IPM_SELFTEST_FRU_ERROR) {
|
||||
printf("FRU device not accessible\n");
|
||||
}
|
||||
if (sft_res->test & IPM_SELFTEST_IPMB_ERROR) {
|
||||
printf("IPMB signal lines do not respond\n");
|
||||
}
|
||||
if (sft_res->test & IPM_SELFTEST_SDRR_EMPTY) {
|
||||
printf("SDR repository empty\n");
|
||||
}
|
||||
if (sft_res->test & IPM_SELFTEST_INTERNAL_USE) {
|
||||
printf("Internal Use Area corrupted\n");
|
||||
}
|
||||
if (sft_res->test & IPM_SELFTEST_FW_BOOTBLOCK) {
|
||||
printf("Controller update boot block corrupted\n");
|
||||
}
|
||||
if (sft_res->test & IPM_SELFTEST_FW_CORRUPTED) {
|
||||
printf("controller operational firmware corrupted\n");
|
||||
}
|
||||
}
|
||||
else if (sft_res->code == IPM_SFT_CODE_FATAL_ERROR) {
|
||||
printf("Selftest : fatal error\n");
|
||||
printf("Failure code : %02x\n", sft_res->test);
|
||||
rv = -1;
|
||||
}
|
||||
else if (sft_res->code == IPM_SFT_CODE_RESERVED) {
|
||||
printf("Selftest: N/A");
|
||||
rv = -1;
|
||||
}
|
||||
else {
|
||||
printf("Selttest : device specific\n");
|
||||
printf("Failure code : %02x\n", sft_res->test);
|
||||
rv = 0;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* ipmi_mc_main - top-level handler for MC functions
|
||||
*
|
||||
* @intf: ipmi interface
|
||||
@ -404,12 +559,18 @@ ipmi_mc_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
else if (strncmp(argv[0], "info", 4) == 0) {
|
||||
rc = ipmi_mc_get_deviceid(intf);
|
||||
}
|
||||
else if (strncmp(argv[0], "guid", 4) == 0) {
|
||||
rc = ipmi_mc_get_guid(intf);
|
||||
}
|
||||
else if (strncmp(argv[0], "getenables", 10) == 0) {
|
||||
rc = ipmi_mc_get_enables(intf);
|
||||
}
|
||||
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)) {
|
||||
rc = ipmi_mc_get_selftest(intf);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -45,12 +45,20 @@ static int ipmi_oem_supermicro(struct ipmi_intf * intf);
|
||||
static struct ipmi_oem_handle ipmi_oem_list[] = {
|
||||
{
|
||||
name: "supermicro",
|
||||
desc: "Supermicro BMC with OEM LAN authentication support",
|
||||
desc: "Supermicro IPMIv1.5 BMC with OEM LAN authentication support",
|
||||
setup: ipmi_oem_supermicro,
|
||||
},
|
||||
{
|
||||
name: "intelwv2",
|
||||
desc: "Intel SE7501WV2 BMC with extra LAN communication support",
|
||||
desc: "Intel SE7501WV2 IPMIv1.5 BMC with extra LAN communication support",
|
||||
},
|
||||
{
|
||||
name: "intelplus",
|
||||
desc: "Intel IPMI 2.0 BMC with RMCP+ communication support",
|
||||
},
|
||||
{
|
||||
name: "icts",
|
||||
desc: "IPMI 2.0 ICTS compliance support",
|
||||
},
|
||||
{ 0 },
|
||||
};
|
||||
@ -70,9 +78,7 @@ ipmi_oem_print(void)
|
||||
{
|
||||
struct ipmi_oem_handle * oem;
|
||||
lprintf(LOG_NOTICE, "\nOEM Support:");
|
||||
for (oem=ipmi_oem_list; oem->setup != NULL; oem++) {
|
||||
if (oem->name == NULL || oem->desc == NULL)
|
||||
continue;
|
||||
for (oem=ipmi_oem_list; oem->name != NULL && oem->desc != NULL; oem++) {
|
||||
lprintf(LOG_NOTICE, "\t%-12s %s", oem->name, oem->desc);
|
||||
}
|
||||
lprintf(LOG_NOTICE, "");
|
||||
@ -90,6 +96,7 @@ 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 ||
|
||||
@ -99,7 +106,7 @@ ipmi_oem_setup(struct ipmi_intf * intf, char * oemtype)
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (oem=ipmi_oem_list; oem->setup != NULL; oem++) {
|
||||
for (oem=ipmi_oem_list, i=0; i < sizeof(ipmi_oem_list)/sizeof(struct ipmi_oem_handle); oem++, i++) {
|
||||
if (oem->name == NULL)
|
||||
continue;
|
||||
if (strncmp(oemtype, oem->name, strlen(oem->name)) == 0)
|
||||
|
@ -76,12 +76,6 @@ static const char * pef_flag_fmts[][3] = {
|
||||
{"active", "in", ""},
|
||||
{"abled", "dis", "en"},
|
||||
};
|
||||
typedef enum {
|
||||
P_TRUE,
|
||||
P_SUPP,
|
||||
P_ACTV,
|
||||
P_ABLE,
|
||||
} flg_e;
|
||||
static const char * listitem[] = {" | %s", ",%s", "%s"};
|
||||
|
||||
const char *
|
||||
@ -291,8 +285,8 @@ ipmi_pef_print_lan_dest(struct ipmi_intf * intf, uint8_t ch, uint8_t dest)
|
||||
return;
|
||||
}
|
||||
tbl_size = (rsp->data[1] & PEF_LAN_DEST_TABLE_SIZE_MASK);
|
||||
if (!dest || tbl_size == 0) /* LAN alerting not supported */
|
||||
return;
|
||||
//if (tbl_size == 0 || dest == 0) /* LAN alerting not supported */
|
||||
// return;
|
||||
|
||||
lsel.id = PEF_LAN_CFGPARM_ID_DESTTYPE;
|
||||
lsel.set = dest;
|
||||
@ -696,7 +690,7 @@ ipmi_pef_list_policies(struct ipmi_intf * intf)
|
||||
|
||||
if (ptmp->entry.alert_string_key & PEF_POLICY_EVENT_SPECIFIC) {
|
||||
ipmi_pef_print_str("Event-specific", "true");
|
||||
continue;
|
||||
// continue;
|
||||
}
|
||||
wrk = ptmp->entry.chan_dest;
|
||||
|
||||
@ -777,6 +771,15 @@ ipmi_pef_get_status(struct ipmi_intf * intf)
|
||||
return;
|
||||
}
|
||||
ipmi_pef_print_flags(&pef_b2s_control, P_ABLE, rsp->data[1]);
|
||||
|
||||
psel.id = PEF_CFGPARM_ID_PEF_ACTION;
|
||||
rsp = ipmi_pef_msg_exchange(intf, &req, "PEF action");
|
||||
if (!rsp) {
|
||||
lprintf(LOG_ERR, " **Error retrieving %s",
|
||||
"PEF action");
|
||||
return;
|
||||
}
|
||||
ipmi_pef_print_flags(&pef_b2s_actions, P_ACTV, rsp->data[1]);
|
||||
}
|
||||
|
||||
static void
|
||||
|
747
ipmitool/lib/ipmi_picmg.c
Normal file
747
ipmitool/lib/ipmi_picmg.c
Normal file
@ -0,0 +1,747 @@
|
||||
|
||||
/*
|
||||
(C) Kontron
|
||||
|
||||
*/
|
||||
|
||||
#include <ipmitool/ipmi_intf.h>
|
||||
#include <ipmitool/ipmi_picmg.h>
|
||||
#include <ipmitool/ipmi_fru.h> /* for access to link descriptor defines */
|
||||
|
||||
|
||||
int
|
||||
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");
|
||||
}
|
||||
|
||||
int
|
||||
ipmi_picmg_getaddr(struct ipmi_intf * intf)
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
unsigned char msg_data;
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.msg.netfn = IPMI_NETFN_PICMG;
|
||||
req.msg.cmd = PICMG_GET_ADDRESS_INFO_CMD;
|
||||
req.msg.data = &msg_data;
|
||||
req.msg.data_len = 1;
|
||||
msg_data = 0;
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (!rsp || rsp->ccode) {
|
||||
printf("Error getting address information\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("Hardware Address : 0x%02x\n", rsp->data[1]);
|
||||
printf("IPMB-0 Address : 0x%02x\n", rsp->data[2]);
|
||||
printf("FRU ID : 0x%02x\n", rsp->data[4]);
|
||||
printf("Site ID : 0x%02x\n", rsp->data[5]);
|
||||
|
||||
printf("Site Type : ");
|
||||
switch (rsp->data[6]) {
|
||||
case PICMG_ATCA_BOARD:
|
||||
printf("ATCA board\n");
|
||||
break;
|
||||
case PICMG_POWER_ENTRY:
|
||||
printf("Power Entry Module\n");
|
||||
break;
|
||||
case PICMG_SHELF_FRU:
|
||||
printf("Shelf FRU\n");
|
||||
break;
|
||||
case PICMG_DEDICATED_SHMC:
|
||||
printf("Dedicated Shelf Manager\n");
|
||||
break;
|
||||
case PICMG_FAN_TRAY:
|
||||
printf("Fan Tray\n");
|
||||
break;
|
||||
case PICMG_FAN_FILTER_TRAY:
|
||||
printf("Fan Filter Tray\n");
|
||||
break;
|
||||
case PICMG_ALARM:
|
||||
printf("Alarm module\n");
|
||||
break;
|
||||
case PICMG_AMC:
|
||||
printf("AMC\n");
|
||||
break;
|
||||
case PICMG_PMC:
|
||||
printf("PMC\n");
|
||||
break;
|
||||
case PICMG_RTM:
|
||||
printf("RTM\n");
|
||||
break;
|
||||
default:
|
||||
if (rsp->data[6] >= 0xc0 && rsp->data[6] <= 0xcf) {
|
||||
printf("OEM\n");
|
||||
} else {
|
||||
printf("unknown\n");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ipmi_picmg_properties(struct ipmi_intf * intf)
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
unsigned char msg_data;
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.msg.netfn = IPMI_NETFN_PICMG;
|
||||
req.msg.cmd = PICMG_GET_PICMG_PROPERTIES_CMD;
|
||||
req.msg.data = &msg_data;
|
||||
req.msg.data_len = 1;
|
||||
msg_data = 0;
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (!rsp || rsp->ccode) {
|
||||
printf("Error getting address information\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("PICMG identifier : 0x%02x\n", rsp->data[0]);
|
||||
printf("PICMG Ext. Version : %i.%i\n", rsp->data[1]&0x0f, (rsp->data[1]&0xf0) >> 4);
|
||||
printf("Max FRU Device ID : 0x%02x\n", rsp->data[2]);
|
||||
printf("FRU Device ID : 0x%02x\n", rsp->data[3]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define PICMG_FRU_DEACTIVATE (unsigned char) 0x00
|
||||
#define PICMG_FRU_ACTIVATE (unsigned char) 0x01
|
||||
|
||||
int
|
||||
ipmi_picmg_fru_activation(struct ipmi_intf * intf, int argc, char ** argv, unsigned char state)
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
|
||||
struct picmg_set_fru_activation_cmd cmd;
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.msg.netfn = IPMI_NETFN_PICMG;
|
||||
req.msg.cmd = PICMG_FRU_ACTIVATION_CMD;
|
||||
req.msg.data = (unsigned char*) &cmd;
|
||||
req.msg.data_len = 3;
|
||||
|
||||
cmd.picmg_id = 0; /* PICMG identifier */
|
||||
cmd.fru_id = (unsigned char) atoi(argv[0]); /* FRU ID */
|
||||
cmd.fru_state = state;
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
|
||||
if (!rsp || rsp->ccode) {
|
||||
printf("Error activation/deactivation of FRU\n");
|
||||
return -1;
|
||||
}
|
||||
if (rsp->data[0] != 0x00) {
|
||||
printf("Error\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ipmi_picmg_fru_activation_policy_get(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
|
||||
unsigned char msg_data[4];
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.msg.netfn = IPMI_NETFN_PICMG;
|
||||
req.msg.cmd = PICMG_GET_FRU_POLICY_CMD;
|
||||
req.msg.data = msg_data;
|
||||
req.msg.data_len = 2;
|
||||
|
||||
msg_data[0] = 0; /* PICMG identifier */
|
||||
msg_data[1] = (unsigned char) atoi(argv[0]); /* FRU ID */
|
||||
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
|
||||
if (!rsp) {
|
||||
printf("no response\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rsp->ccode) {
|
||||
printf("returned CC code 0x%02x\n", rsp->ccode);
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("Activation Policy for FRU %x: ", atoi(argv[0]) );
|
||||
printf(" %s\n",(*(rsp->data+3)&0x01 == 0x01)?"is locked":"is not locked");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ipmi_picmg_portstate_get(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
|
||||
unsigned char msg_data[4];
|
||||
|
||||
struct fru_picmgext_link_desc* d; /* descriptor pointer for rec. data */
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
|
||||
req.msg.netfn = IPMI_NETFN_PICMG;
|
||||
req.msg.cmd = PICMG_GET_PORT_STATE_CMD;
|
||||
req.msg.data = msg_data;
|
||||
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 */
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
|
||||
if (!rsp) {
|
||||
printf("no response\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rsp->ccode) {
|
||||
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]);
|
||||
|
||||
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: ");
|
||||
switch ((d->designator & 0xff) >> 6)
|
||||
{
|
||||
case FRU_PICMGEXT_DESIGN_IF_BASE:
|
||||
printf("Base Interface\n");
|
||||
break;
|
||||
case FRU_PICMGEXT_DESIGN_IF_FABRIC:
|
||||
printf("Fabric Interface\n");
|
||||
break;
|
||||
case FRU_PICMGEXT_DESIGN_IF_UPDATE_CHANNEL:
|
||||
printf("Update Channel\n");
|
||||
break;
|
||||
case FRU_PICMGEXT_DESIGN_IF_RESERVED:
|
||||
printf("Reserved\n");
|
||||
default:
|
||||
printf("Invalid");
|
||||
}
|
||||
printf(" Channel Number: 0x%02x\n", d->designator & 0x1f);
|
||||
printf("\n");
|
||||
printf(" STATE: %s\n", rsp->data[5] == 0x01?"enabled":"disabled");
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ipmi_picmg_portstate_set(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
|
||||
unsigned char msg_data[6];
|
||||
struct fru_picmgext_link_desc* d;
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
|
||||
req.msg.netfn = IPMI_NETFN_PICMG;
|
||||
req.msg.cmd = PICMG_SET_PORT_STATE_CMD;
|
||||
req.msg.data = msg_data;
|
||||
req.msg.data_len = 6;
|
||||
|
||||
msg_data[0] = 0x00; /* PICMG identifier */
|
||||
|
||||
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->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 */
|
||||
|
||||
msg_data[5] = (unsigned char) (atoi(argv[6]) & 0x01); /* en/dis */
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
|
||||
if (!rsp) {
|
||||
printf("no response\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rsp->ccode) {
|
||||
printf("returned CC code 0x%02x\n", rsp->ccode);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ipmi_picmg_get_led_properties(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
|
||||
unsigned char msg_data[6];
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
|
||||
req.msg.netfn = IPMI_NETFN_PICMG;
|
||||
req.msg.cmd = PICMG_GET_FRU_LED_PROPERTIES_CMD;
|
||||
req.msg.data = msg_data;
|
||||
req.msg.data_len = 2;
|
||||
|
||||
msg_data[0] = 0x00; /* PICMG identifier */
|
||||
msg_data[1] = atoi(argv[0]); /* FRU-ID */
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
|
||||
if (!rsp) {
|
||||
printf("no response\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rsp->ccode) {
|
||||
printf("returned CC code 0x%02x\n", rsp->ccode);
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("General Status LED Properties: 0x%2x\n\r", rsp->data[1] );
|
||||
printf("App. Specific LED Count: 0x%2x\n\r", rsp->data[2] );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ipmi_picmg_get_led_capabilities(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
{
|
||||
int i;
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
|
||||
unsigned char msg_data[6];
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
|
||||
req.msg.netfn = IPMI_NETFN_PICMG;
|
||||
req.msg.cmd = PICMG_GET_LED_COLOR_CAPABILITIES_CMD;
|
||||
req.msg.data = msg_data;
|
||||
req.msg.data_len = 3;
|
||||
|
||||
msg_data[0] = 0x00; /* PICMG identifier */
|
||||
msg_data[1] = atoi(argv[0]); /* FRU-ID */
|
||||
msg_data[2] = atoi(argv[1]); /* LED-ID */
|
||||
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
|
||||
if (!rsp) {
|
||||
printf("no response\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rsp->ccode) {
|
||||
printf("returned CC code 0x%02x\n", rsp->ccode);
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("LED Color Capabilities: ", rsp->data[1] );
|
||||
for ( i=0 ; i<8 ; i++ ) {
|
||||
if ( rsp->data[1] & (0x01 << i) ) {
|
||||
printf("%s, ", led_color_str[ i ]);
|
||||
}
|
||||
}
|
||||
printf("\n\r");
|
||||
|
||||
printf("Default LED Color in\n\r");
|
||||
printf(" LOCAL control: %s\n\r", led_color_str[ rsp->data[2] ] );
|
||||
printf(" OVERRIDE state: %s\n\r", led_color_str[ rsp->data[3] ] );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ipmi_picmg_get_led_state(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
{
|
||||
int i;
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
|
||||
unsigned char msg_data[6];
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
|
||||
req.msg.netfn = IPMI_NETFN_PICMG;
|
||||
req.msg.cmd = PICMG_GET_FRU_LED_STATE_CMD;
|
||||
req.msg.data = msg_data;
|
||||
req.msg.data_len = 3;
|
||||
|
||||
msg_data[0] = 0x00; /* PICMG identifier */
|
||||
msg_data[1] = atoi(argv[0]); /* FRU-ID */
|
||||
msg_data[2] = atoi(argv[1]); /* LED-ID */
|
||||
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
|
||||
if (!rsp) {
|
||||
printf("no response\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rsp->ccode) {
|
||||
printf("returned CC code 0x%02x\n", rsp->ccode);
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("LED states: %x\n\r", rsp->data[1] );
|
||||
printf(" Local Control function: %x\n\r", rsp->data[2] );
|
||||
printf(" Local Control On-Duration: %x\n\r", rsp->data[3] );
|
||||
printf(" Local Control Color: %s\n\r", led_color_str[ rsp->data[4] ]);
|
||||
|
||||
/* override state or lamp test */
|
||||
if (rsp->data[1] == 0x01) {
|
||||
printf(" Override function: %x\n\r", rsp->data[5] );
|
||||
printf(" Override On-Duration: %x\n\r", rsp->data[6] );
|
||||
printf(" Override Color: %s\n\r", led_color_str[ rsp->data[7] ]);
|
||||
|
||||
}else if (rsp->data[1] == 0x03) {
|
||||
printf(" Override function: %x\n\r", rsp->data[5] );
|
||||
printf(" Override On-Duration: %x\n\r", rsp->data[6] );
|
||||
printf(" Override Color: %s\n\r", led_color_str[ rsp->data[7] ]);
|
||||
printf(" Lamp test duration: %x\n\r", rsp->data[8] );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ipmi_picmg_set_led_state(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
{
|
||||
int i;
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
|
||||
unsigned char msg_data[6];
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
|
||||
req.msg.netfn = IPMI_NETFN_PICMG;
|
||||
req.msg.cmd = PICMG_SET_FRU_LED_STATE_CMD;
|
||||
req.msg.data = msg_data;
|
||||
req.msg.data_len = 6;
|
||||
|
||||
msg_data[0] = 0x00; /* PICMG identifier */
|
||||
msg_data[1] = atoi(argv[0]); /* FRU-ID */
|
||||
msg_data[2] = atoi(argv[1]); /* LED-ID */
|
||||
msg_data[3] = atoi(argv[2]); /* LED function */
|
||||
msg_data[4] = atoi(argv[3]); /* LED on duration */
|
||||
msg_data[5] = atoi(argv[4]); /* LED color */
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
|
||||
if (!rsp) {
|
||||
printf("no response\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rsp->ccode) {
|
||||
printf("returned CC code 0x%02x\n", rsp->ccode);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ipmi_picmg_get_power_level(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
{
|
||||
int i;
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
|
||||
unsigned char msg_data[6];
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
|
||||
req.msg.netfn = IPMI_NETFN_PICMG;
|
||||
req.msg.cmd = PICMG_GET_POWER_LEVEL_CMD;
|
||||
req.msg.data = msg_data;
|
||||
req.msg.data_len = 3;
|
||||
|
||||
msg_data[0] = 0x00; /* PICMG identifier */
|
||||
msg_data[1] = atoi(argv[0]); /* FRU-ID */
|
||||
msg_data[2] = atoi(argv[1]); /* Power type */
|
||||
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
|
||||
if (!rsp) {
|
||||
printf("no response\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rsp->ccode) {
|
||||
printf("returned CC code 0x%02x\n", rsp->ccode);
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("Dynamic Power Configuration: %s\n", (rsp->data[1]&0x80)==0x80?"enabled":"disabled" );
|
||||
printf("Actual Power Level: %i\n", (rsp->data[1] & 0xf));
|
||||
printf("Delay to stable Power: %i\n", rsp->data[2]);
|
||||
printf("Power Multiplier: %i\n", rsp->data[3]);
|
||||
|
||||
|
||||
for ( i = 1; i+3 < rsp->data_len ; i++ ) {
|
||||
printf(" Power Draw %i: %i\n", i, rsp->data[i+3]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ipmi_picmg_main (struct ipmi_intf * intf, int argc, char ** argv)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (argc == 0 || (!strncmp(argv[0], "help", 4))) {
|
||||
ipmi_picmg_help();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* address info command */
|
||||
else if (!strncmp(argv[0], "addrinfo", 8)) {
|
||||
rc = ipmi_picmg_getaddr(intf);
|
||||
}
|
||||
|
||||
/* picmg properties command */
|
||||
else if (!strncmp(argv[0], "properties", 10)) {
|
||||
rc = ipmi_picmg_properties(intf);
|
||||
}
|
||||
|
||||
/* fru activation command */
|
||||
else if (!strncmp(argv[0], "activate", 8)) {
|
||||
if (argc > 1) {
|
||||
rc = ipmi_picmg_fru_activation(intf, argc-1, &(argv[1]), PICMG_FRU_ACTIVATE);
|
||||
}
|
||||
else {
|
||||
printf("specify the FRU to activate\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* fru deactivation command */
|
||||
else if (!strncmp(argv[0], "deactivate", 10)) {
|
||||
if (argc > 1) {
|
||||
rc = ipmi_picmg_fru_activation(intf, argc-1, &(argv[1]), PICMG_FRU_DEACTIVATE);
|
||||
}else {
|
||||
printf("specify the FRU to deactivate\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* activation policy command */
|
||||
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]));
|
||||
}
|
||||
else if (!strncmp(argv[1], "set", 6)) {
|
||||
printf("tbd\n");
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
printf("specify fru\n");
|
||||
return -1;
|
||||
}
|
||||
}else {
|
||||
printf("wrong parameters\n");
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("<set>|<get>\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* ATCA led commands */
|
||||
else if (!strncmp(argv[0], "led", 3)) {
|
||||
if (argc > 1) {
|
||||
if (!strncmp(argv[1], "prop", 4)) {
|
||||
if (argc > 2) {
|
||||
rc = ipmi_picmg_get_led_properties(intf, argc-1, &(argv[2]));
|
||||
}
|
||||
else {
|
||||
printf("led prop <FRU-ID>\n");
|
||||
}
|
||||
}
|
||||
else if (!strncmp(argv[1], "cap", 3)) {
|
||||
if (argc > 3) {
|
||||
rc = ipmi_picmg_get_led_capabilities(intf, argc-1, &(argv[2]));
|
||||
}
|
||||
else {
|
||||
printf("led cap <FRU-ID> <LED-ID>\n");
|
||||
}
|
||||
}
|
||||
else if (!strncmp(argv[1], "get", 3)) {
|
||||
if (argc > 3) {
|
||||
rc = ipmi_picmg_get_led_state(intf, argc-1, &(argv[2]));
|
||||
}
|
||||
else {
|
||||
printf("led get <FRU-ID> <LED-ID>\n");
|
||||
}
|
||||
}
|
||||
else if (!strncmp(argv[1], "set", 3)) {
|
||||
if (argc > 6) {
|
||||
rc = ipmi_picmg_set_led_state(intf, argc-1, &(argv[2]));
|
||||
}
|
||||
else {
|
||||
printf("led set <FRU-ID> <LED-ID> <function> <duration> <color>\n");
|
||||
printf(" <FRU-ID>\n");
|
||||
printf(" <LED-ID>\n");
|
||||
printf(" <function> 0: LED OFF override\n");
|
||||
printf(" 1 - 250: LED blinking override (off duration)\n");
|
||||
printf(" 251: LED Lamp Test\n");
|
||||
printf(" 252: LED restore to local control\n");
|
||||
printf(" 255: LED ON override\n");
|
||||
printf(" <duration> 1 - 127: LED Lamp Test / on duration\n");
|
||||
printf(" <color> \n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("prop | cap | get | set\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
/* power commands */
|
||||
else if (!strncmp(argv[0], "power", 5)) {
|
||||
if (argc > 1) {
|
||||
if (!strncmp(argv[1], "get", 3)) {
|
||||
if (argc > 3) {
|
||||
rc = ipmi_picmg_get_power_level(intf, argc-1, &(argv[2]));
|
||||
}
|
||||
else {
|
||||
printf("power get <FRI-ID> <type>\n");
|
||||
printf(" <type> 0 : steady state powert draw levels\n");
|
||||
printf(" 1 : desired steady state draw levels\n");
|
||||
printf(" 2 : early power draw levels\n");
|
||||
printf(" 3 : desired early levels\n");
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if (!strncmp(argv[1], "set", 3)) {
|
||||
if (argc > 5) {
|
||||
printf("not implemented yet\n");
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("<set>|<get>\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("<set>|<get>\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
ipmi_picmg_help();
|
||||
return -1;
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
||||
}
|
@ -43,27 +43,213 @@
|
||||
#include <ipmitool/helper.h>
|
||||
#include <ipmitool/ipmi_intf.h>
|
||||
#include <ipmitool/ipmi_raw.h>
|
||||
#include <ipmitool/ipmi_strings.h>
|
||||
|
||||
#define IPMI_I2C_MASTER_MAX_SIZE 0x40
|
||||
|
||||
/* ipmi_master_write_read - Perform I2C write/read transactions
|
||||
*
|
||||
* This function performs an I2C master write-read function through
|
||||
* IPMI interface. It has a maximum transfer size of 32 bytes.
|
||||
*
|
||||
* @intf: ipmi interface
|
||||
* @addr: i2c slave address
|
||||
* @wdata: data to write
|
||||
* @wsize: length of data to write (max 64 bytes)
|
||||
* @rsize: length of data to read (max 64 bytes)
|
||||
*
|
||||
* 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)
|
||||
{
|
||||
struct ipmi_rq req;
|
||||
struct ipmi_rs * rsp;
|
||||
uint8_t rqdata[IPMI_I2C_MASTER_MAX_SIZE + 3];
|
||||
|
||||
if (rsize > IPMI_I2C_MASTER_MAX_SIZE) {
|
||||
lprintf(LOG_ERR, "Master Write-Read: Too many bytes (%d) to read", rsize);
|
||||
return NULL;
|
||||
}
|
||||
if (wsize > IPMI_I2C_MASTER_MAX_SIZE) {
|
||||
lprintf(LOG_ERR, "Master Write-Read: Too many bytes (%d) to write", wsize);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(&req, 0, sizeof(struct ipmi_rq));
|
||||
req.msg.netfn = IPMI_NETFN_APP;
|
||||
req.msg.cmd = 0x52; /* master write-read */
|
||||
req.msg.data = rqdata;
|
||||
req.msg.data_len = 3;
|
||||
|
||||
memset(rqdata, 0, IPMI_I2C_MASTER_MAX_SIZE + 3);
|
||||
rqdata[0] = 0x00; /* channel number, bus id, bus type */
|
||||
rqdata[1] = addr; /* slave address */
|
||||
rqdata[2] = rsize; /* number of bytes to read */
|
||||
|
||||
if (wsize > 0) {
|
||||
/* copy in data to write */
|
||||
memcpy(rqdata+3, wdata, wsize);
|
||||
req.msg.data_len += wsize;
|
||||
lprintf(LOG_DEBUG, "Writing %d bytes to i2cdev %02Xh", wsize, addr);
|
||||
}
|
||||
|
||||
if (rsize > 0) {
|
||||
lprintf(LOG_DEBUG, "Reading %d bytes from i2cdev %02Xh", rsize, addr);
|
||||
}
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (rsp == NULL) {
|
||||
lprintf(LOG_ERR, "I2C Master Write-Read command failed");
|
||||
return NULL;
|
||||
}
|
||||
else if (rsp->ccode > 0) {
|
||||
switch (rsp->ccode) {
|
||||
case 0x81:
|
||||
lprintf(LOG_ERR, "I2C Master Write-Read command failed: Lost Arbitration");
|
||||
break;
|
||||
case 0x82:
|
||||
lprintf(LOG_ERR, "I2C Master Write-Read command failed: Bus Error");
|
||||
break;
|
||||
case 0x83:
|
||||
lprintf(LOG_ERR, "I2C Master Write-Read command failed: NAK on Write");
|
||||
break;
|
||||
case 0x84:
|
||||
lprintf(LOG_ERR, "I2C Master Write-Read command failed: Truncated Read");
|
||||
break;
|
||||
default:
|
||||
lprintf(LOG_ERR, "I2C Master Write-Read command failed: %s",
|
||||
val2str(rsp->ccode, completion_code_vals));
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return rsp;
|
||||
}
|
||||
|
||||
static void rawi2c_usage(void)
|
||||
{
|
||||
lprintf(LOG_NOTICE, "usage: i2c <i2caddr> <read bytes> [write data]");
|
||||
}
|
||||
|
||||
int
|
||||
ipmi_rawi2c_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
uint8_t wdata[IPMI_I2C_MASTER_MAX_SIZE];
|
||||
uint8_t i2caddr = 0;
|
||||
uint8_t rsize = 0;
|
||||
uint8_t wsize = 0;
|
||||
int i;
|
||||
|
||||
if (argc < 2 || strncmp(argv[0], "help", 4) == 0) {
|
||||
rawi2c_usage();
|
||||
return 0;
|
||||
}
|
||||
else if (argc-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);
|
||||
|
||||
if (i2caddr == 0) {
|
||||
lprintf(LOG_ERR, "Invalid I2C address 0");
|
||||
rawi2c_usage();
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(wdata, 0, IPMI_I2C_MASTER_MAX_SIZE);
|
||||
for (i=2; i<argc; i++) {
|
||||
uint8_t val = (uint8_t)strtol(argv[i], NULL, 0);
|
||||
wdata[i-2] = val;
|
||||
wsize++;
|
||||
}
|
||||
|
||||
lprintf(LOG_INFO, "RAW I2C REQ (i2caddr=%x readbytes=%d writebytes=%d)",
|
||||
i2caddr, rsize, wsize);
|
||||
printbuf(wdata, wsize, "WRITE DATA");
|
||||
|
||||
rsp = ipmi_master_write_read(intf, i2caddr, wdata, wsize, rsize);
|
||||
if (rsp == NULL) {
|
||||
lprintf(LOG_ERR, "Unable to perform I2C Master Write-Read");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (wsize > 0) {
|
||||
if (verbose || rsize == 0)
|
||||
printf("Wrote %d bytes to I2C device %02Xh\n", wsize, i2caddr);
|
||||
}
|
||||
|
||||
if (rsize > 0) {
|
||||
if (verbose || wsize == 0)
|
||||
printf("Read %d bytes from I2C device %02Xh\n", rsp->data_len, i2caddr);
|
||||
|
||||
/* print the raw response buffer */
|
||||
for (i=0; i<rsp->data_len; i++) {
|
||||
if (((i%16) == 0) && (i != 0))
|
||||
printf("\n");
|
||||
printf(" %2.2x", rsp->data[i]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
if (rsp->data_len <= 4) {
|
||||
uint32_t bit;
|
||||
int j;
|
||||
for (i = 0; i < rsp->data_len; i++) {
|
||||
for (j = 1, bit = 0x80; bit > 0; bit /= 2, j++) {
|
||||
printf("%s", (rsp->data[i] & bit) ? "1" : "0");
|
||||
}
|
||||
printf(" ");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ipmi_raw_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
uint8_t netfn, cmd;
|
||||
uint8_t netfn, cmd, lun;
|
||||
int i;
|
||||
uint8_t data[32];
|
||||
unsigned long ufn;
|
||||
|
||||
uint8_t data[256];
|
||||
|
||||
if (argc < 2 || strncmp(argv[0], "help", 4) == 0) {
|
||||
lprintf(LOG_NOTICE, "RAW Commands: raw <netfn> <cmd> [data]");
|
||||
print_valstr(ipmi_netfn_vals, "Network Function Codes", LOG_NOTICE);
|
||||
lprintf(LOG_NOTICE, "(can also use raw hex values)");
|
||||
return -1;
|
||||
}
|
||||
else if (argc > sizeof(data))
|
||||
{
|
||||
lprintf(LOG_NOTICE, "Raw command input limit (256 bytes) exceeded");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ipmi_intf_session_set_timeout(intf, 15);
|
||||
ipmi_intf_session_set_retry(intf, 1);
|
||||
|
||||
lun = intf->target_lun;
|
||||
netfn = str2val(argv[0], ipmi_netfn_vals);
|
||||
if (netfn == 0xff) {
|
||||
netfn = (uint8_t)strtol(argv[0], NULL, 0);
|
||||
}
|
||||
|
||||
cmd = (uint8_t)strtol(argv[1], NULL, 0);
|
||||
|
||||
memset(data, 0, sizeof(data));
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.msg.netfn = netfn;
|
||||
req.msg.lun = lun;
|
||||
req.msg.cmd = cmd;
|
||||
req.msg.data = data;
|
||||
|
||||
@ -73,8 +259,10 @@ ipmi_raw_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
req.msg.data_len++;
|
||||
}
|
||||
|
||||
lprintf(LOG_INFO, "RAW REQ (netfn=0x%x cmd=0x%x data_len=%d)",
|
||||
req.msg.netfn, req.msg.cmd, req.msg.data_len);
|
||||
lprintf(LOG_INFO,
|
||||
"RAW REQ (channel=0x%x netfn=0x%x lun=0x%x cmd=0x%x data_len=%d)",
|
||||
intf->target_channel & 0x0f, req.msg.netfn,req.msg.lun ,
|
||||
req.msg.cmd, req.msg.data_len);
|
||||
|
||||
printbuf(req.msg.data, req.msg.data_len, "RAW REQUEST");
|
||||
|
||||
@ -82,14 +270,14 @@ ipmi_raw_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
|
||||
if (rsp == NULL) {
|
||||
lprintf(LOG_ERR, "Unable to send RAW command "
|
||||
"(netfn=0x%x cmd=0x%x)",
|
||||
req.msg.netfn, req.msg.cmd);
|
||||
"(channel=0x%x netfn=0x%x lun=0x%x cmd=0x%x)",
|
||||
intf->target_channel & 0x0f, req.msg.netfn, req.msg.lun, req.msg.cmd);
|
||||
return -1;
|
||||
}
|
||||
if (rsp->ccode > 0) {
|
||||
lprintf(LOG_ERR, "Unable to send RAW command "
|
||||
"(netfn=0x%x cmd=0x%x): %s",
|
||||
req.msg.netfn, req.msg.cmd,
|
||||
"(channel=0x%x netfn=0x%x lun=0x%x cmd=0x%x rsp=0x%x): %s",
|
||||
intf->target_channel & 0x0f, req.msg.netfn, req.msg.lun, req.msg.cmd, rsp->ccode,
|
||||
val2str(rsp->ccode, completion_code_vals));
|
||||
return -1;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -51,30 +51,14 @@ extern int verbose;
|
||||
|
||||
static
|
||||
struct ipmi_rs *
|
||||
ipmi_sensor_get_sensor_thresholds(struct ipmi_intf * intf, uint8_t sensor)
|
||||
{
|
||||
struct ipmi_rq req;
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.msg.netfn = IPMI_NETFN_SE;
|
||||
req.msg.cmd = GET_SENSOR_THRESHOLDS;
|
||||
req.msg.data = &sensor;
|
||||
req.msg.data_len = sizeof(sensor);
|
||||
|
||||
return intf->sendrecv(intf, &req);
|
||||
}
|
||||
|
||||
static
|
||||
struct ipmi_rs *
|
||||
ipmi_sensor_set_sensor_thresholds(struct ipmi_intf * intf,
|
||||
ipmi_sensor_set_sensor_thresholds(struct ipmi_intf *intf,
|
||||
uint8_t sensor,
|
||||
uint8_t threshold,
|
||||
uint8_t setting)
|
||||
uint8_t threshold, uint8_t setting)
|
||||
{
|
||||
struct ipmi_rq req;
|
||||
static struct sensor_set_thresh_rq set_thresh_rq;
|
||||
|
||||
memset(&set_thresh_rq, 0, sizeof(set_thresh_rq));
|
||||
memset(&set_thresh_rq, 0, sizeof (set_thresh_rq));
|
||||
set_thresh_rq.sensor_num = sensor;
|
||||
set_thresh_rq.set_mask = threshold;
|
||||
if (threshold == UPPER_NON_RECOV_SPECIFIED)
|
||||
@ -92,35 +76,37 @@ ipmi_sensor_set_sensor_thresholds(struct ipmi_intf * intf,
|
||||
else
|
||||
return NULL;
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
memset(&req, 0, sizeof (req));
|
||||
req.msg.netfn = IPMI_NETFN_SE;
|
||||
req.msg.cmd = SET_SENSOR_THRESHOLDS;
|
||||
req.msg.data = (uint8_t *)&set_thresh_rq;
|
||||
req.msg.data_len = sizeof(set_thresh_rq);
|
||||
req.msg.data = (uint8_t *) & set_thresh_rq;
|
||||
req.msg.data_len = sizeof (set_thresh_rq);
|
||||
|
||||
return intf->sendrecv(intf, &req);
|
||||
}
|
||||
|
||||
static int
|
||||
ipmi_sensor_print_full_discrete(struct ipmi_intf * intf,
|
||||
struct sdr_record_full_sensor * sensor)
|
||||
ipmi_sensor_print_full_discrete(struct ipmi_intf *intf,
|
||||
struct sdr_record_full_sensor *sensor)
|
||||
{
|
||||
char id[17];
|
||||
char * unitstr = "discrete";
|
||||
int validread=1;
|
||||
char *unitstr = "discrete";
|
||||
int validread = 1;
|
||||
uint8_t val = 0;
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rs *rsp;
|
||||
|
||||
if (sensor == NULL)
|
||||
return -1;
|
||||
|
||||
memset(id, 0, sizeof(id));
|
||||
memset(id, 0, sizeof (id));
|
||||
memcpy(id, sensor->id_string, 16);
|
||||
|
||||
/*
|
||||
* Get current reading
|
||||
*/
|
||||
rsp = ipmi_sdr_get_sensor_reading(intf, sensor->keys.sensor_num);
|
||||
rsp = ipmi_sdr_get_sensor_reading_ipmb(intf,
|
||||
sensor->keys.sensor_num,
|
||||
sensor->keys.owner_id);
|
||||
if (rsp == NULL) {
|
||||
lprintf(LOG_ERR, "Error reading sensor %s (#%02x)",
|
||||
id, sensor->keys.sensor_num);
|
||||
@ -132,12 +118,9 @@ ipmi_sensor_print_full_discrete(struct ipmi_intf * intf,
|
||||
val = rsp->data[0];
|
||||
}
|
||||
|
||||
if (csv_output)
|
||||
{
|
||||
if (csv_output) {
|
||||
/* NOT IMPLEMENTED */
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
if (verbose == 0) {
|
||||
/* output format
|
||||
* id value units status thresholds....
|
||||
@ -146,14 +129,10 @@ ipmi_sensor_print_full_discrete(struct ipmi_intf * intf,
|
||||
if (validread) {
|
||||
printf("| 0x%-8x | %-10s | 0x%02x%02x",
|
||||
val,
|
||||
unitstr,
|
||||
rsp->data[2],
|
||||
rsp->data[3]);
|
||||
unitstr, rsp->data[2], rsp->data[3]);
|
||||
} else {
|
||||
printf("| %-10s | %-10s | %-6s",
|
||||
"na",
|
||||
unitstr,
|
||||
"na");
|
||||
"na", unitstr, "na");
|
||||
}
|
||||
printf("| %-10s| %-10s| %-10s| %-10s| %-10s| %-10s",
|
||||
"na", "na", "na", "na", "na", "na");
|
||||
@ -165,10 +144,13 @@ ipmi_sensor_print_full_discrete(struct ipmi_intf * intf,
|
||||
printf(" Entity ID : %d.%d\n",
|
||||
sensor->entity.id, sensor->entity.instance);
|
||||
printf(" Sensor Type (Discrete): %s\n",
|
||||
ipmi_sdr_get_sensor_type_desc(sensor->sensor.type));
|
||||
ipmi_sdr_print_discrete_state(sensor->sensor.type,
|
||||
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[2],
|
||||
rsp->data[3]);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
@ -177,32 +159,33 @@ ipmi_sensor_print_full_discrete(struct ipmi_intf * intf,
|
||||
}
|
||||
|
||||
static int
|
||||
ipmi_sensor_print_full_analog(struct ipmi_intf * intf,
|
||||
struct sdr_record_full_sensor * sensor)
|
||||
ipmi_sensor_print_full_analog(struct ipmi_intf *intf,
|
||||
struct sdr_record_full_sensor *sensor)
|
||||
{
|
||||
char unitstr[16], id[17];
|
||||
int i=0, validread=1, thresh_available = 1;
|
||||
float val = 0.0;
|
||||
struct ipmi_rs * rsp;
|
||||
char * status = NULL;
|
||||
int i = 0, validread = 1, thresh_available = 1;
|
||||
double val = 0.0;
|
||||
struct ipmi_rs *rsp;
|
||||
char *status = NULL;
|
||||
|
||||
if (sensor == NULL)
|
||||
return -1;
|
||||
|
||||
/* only handle linear sensors (for now) */
|
||||
if (sensor->linearization) {
|
||||
lprintf(LOG_ERR, "Sensor #%02x is non-linear",
|
||||
sensor->keys.sensor_num);
|
||||
memset(id, 0, sizeof (id));
|
||||
memcpy(id, sensor->id_string, 16);
|
||||
|
||||
/* only handle linear and linearized sensors (for now) */
|
||||
if (sensor->linearization >= SDR_SENSOR_L_NONLINEAR) {
|
||||
printf("sensor %s non-linear!\n", id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(id, 0, sizeof(id));
|
||||
memcpy(id, sensor->id_string, 16);
|
||||
|
||||
/*
|
||||
* Get current reading
|
||||
*/
|
||||
rsp = ipmi_sdr_get_sensor_reading(intf, sensor->keys.sensor_num);
|
||||
rsp = ipmi_sdr_get_sensor_reading_ipmb(intf,
|
||||
sensor->keys.sensor_num,
|
||||
sensor->keys.owner_id);
|
||||
if (rsp == NULL) {
|
||||
lprintf(LOG_ERR, "Error reading sensor %s (#%02x)",
|
||||
id, sensor->keys.sensor_num);
|
||||
@ -214,28 +197,27 @@ ipmi_sensor_print_full_analog(struct ipmi_intf * intf,
|
||||
val = (rsp->data[0] > 0)
|
||||
? sdr_convert_sensor_reading(sensor, rsp->data[0])
|
||||
: 0;
|
||||
status = (char*)ipmi_sdr_get_status(rsp->data[2]);
|
||||
status = (char *) ipmi_sdr_get_status(sensor, rsp->data[2]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Figure out units
|
||||
*/
|
||||
memset(unitstr, 0, sizeof(unitstr));
|
||||
switch (sensor->unit.modifier)
|
||||
{
|
||||
memset(unitstr, 0, sizeof (unitstr));
|
||||
switch (sensor->unit.modifier) {
|
||||
case 2:
|
||||
i += snprintf(unitstr, sizeof(unitstr), "%s * %s",
|
||||
i += snprintf(unitstr, sizeof (unitstr), "%s * %s",
|
||||
unit_desc[sensor->unit.type.base],
|
||||
unit_desc[sensor->unit.type.modifier]);
|
||||
break;
|
||||
case 1:
|
||||
i += snprintf(unitstr, sizeof(unitstr), "%s/%s",
|
||||
i += snprintf(unitstr, sizeof (unitstr), "%s/%s",
|
||||
unit_desc[sensor->unit.type.base],
|
||||
unit_desc[sensor->unit.type.modifier]);
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
i += snprintf(unitstr, sizeof(unitstr), "%s",
|
||||
i += snprintf(unitstr, sizeof (unitstr), "%s",
|
||||
unit_desc[sensor->unit.type.base]);
|
||||
break;
|
||||
}
|
||||
@ -243,18 +225,14 @@ ipmi_sensor_print_full_analog(struct ipmi_intf * intf,
|
||||
/*
|
||||
* Get sensor thresholds
|
||||
*/
|
||||
rsp = ipmi_sensor_get_sensor_thresholds(intf, sensor->keys.sensor_num);
|
||||
rsp = ipmi_sdr_get_sensor_thresholds(intf, sensor->keys.sensor_num);
|
||||
if (rsp == NULL)
|
||||
thresh_available = 0;
|
||||
|
||||
if (csv_output)
|
||||
{
|
||||
if (csv_output) {
|
||||
/* NOT IPMLEMENTED */
|
||||
}
|
||||
else
|
||||
{
|
||||
if (verbose == 0)
|
||||
{
|
||||
} else {
|
||||
if (verbose == 0) {
|
||||
/* output format
|
||||
* id value units status thresholds....
|
||||
*/
|
||||
@ -266,43 +244,51 @@ ipmi_sensor_print_full_analog(struct ipmi_intf * intf,
|
||||
printf("| %-10s | %-10s | %-6s",
|
||||
"na", unitstr, "na");
|
||||
}
|
||||
if (thresh_available)
|
||||
{
|
||||
if (thresh_available) {
|
||||
if (rsp->data[0] & LOWER_NON_RECOV_SPECIFIED)
|
||||
printf("| %-10.3f", sdr_convert_sensor_reading(sensor, rsp->data[3]));
|
||||
printf("| %-10.3f",
|
||||
sdr_convert_sensor_reading
|
||||
(sensor, rsp->data[3]));
|
||||
else
|
||||
printf("| %-10s", "na");
|
||||
if (rsp->data[0] & LOWER_CRIT_SPECIFIED)
|
||||
printf("| %-10.3f", sdr_convert_sensor_reading(sensor, rsp->data[2]));
|
||||
printf("| %-10.3f",
|
||||
sdr_convert_sensor_reading
|
||||
(sensor, rsp->data[2]));
|
||||
else
|
||||
printf("| %-10s", "na");
|
||||
if (rsp->data[0] & LOWER_NON_CRIT_SPECIFIED)
|
||||
printf("| %-10.3f", sdr_convert_sensor_reading(sensor, rsp->data[1]));
|
||||
printf("| %-10.3f",
|
||||
sdr_convert_sensor_reading
|
||||
(sensor, rsp->data[1]));
|
||||
else
|
||||
printf("| %-10s", "na");
|
||||
if (rsp->data[0] & UPPER_NON_CRIT_SPECIFIED)
|
||||
printf("| %-10.3f", sdr_convert_sensor_reading(sensor, rsp->data[4]));
|
||||
printf("| %-10.3f",
|
||||
sdr_convert_sensor_reading
|
||||
(sensor, rsp->data[4]));
|
||||
else
|
||||
printf("| %-10s", "na");
|
||||
if (rsp->data[0] & UPPER_CRIT_SPECIFIED)
|
||||
printf("| %-10.3f", sdr_convert_sensor_reading(sensor, rsp->data[5]));
|
||||
printf("| %-10.3f",
|
||||
sdr_convert_sensor_reading
|
||||
(sensor, rsp->data[5]));
|
||||
else
|
||||
printf("| %-10s", "na");
|
||||
if (rsp->data[0] & UPPER_NON_RECOV_SPECIFIED)
|
||||
printf("| %-10.3f", sdr_convert_sensor_reading(sensor, rsp->data[6]));
|
||||
printf("| %-10.3f",
|
||||
sdr_convert_sensor_reading
|
||||
(sensor, rsp->data[6]));
|
||||
else
|
||||
printf("| %-10s", "na");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("| %-10s| %-10s| %-10s| %-10s| %-10s| %-10s",
|
||||
} else {
|
||||
printf
|
||||
("| %-10s| %-10s| %-10s| %-10s| %-10s| %-10s",
|
||||
"na", "na", "na", "na", "na", "na");
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
printf("Sensor ID : %s (0x%x)\n",
|
||||
id, sensor->keys.sensor_num);
|
||||
|
||||
@ -310,66 +296,103 @@ ipmi_sensor_print_full_analog(struct ipmi_intf * intf,
|
||||
sensor->entity.id, sensor->entity.instance);
|
||||
|
||||
printf(" Sensor Type (Analog) : %s\n",
|
||||
ipmi_sdr_get_sensor_type_desc(sensor->sensor.type));
|
||||
ipmi_sdr_get_sensor_type_desc(sensor->sensor.
|
||||
type));
|
||||
|
||||
printf(" Sensor Reading : ");
|
||||
if (validread) {
|
||||
uint16_t raw_tol = __TO_TOL(sensor->mtol);
|
||||
float tol = sdr_convert_sensor_reading(sensor, raw_tol * 2);
|
||||
double tol =
|
||||
sdr_convert_sensor_reading(sensor,
|
||||
raw_tol * 2);
|
||||
printf("%.*f (+/- %.*f) %s\n",
|
||||
(val==(int)val) ? 0 : 3,
|
||||
val,
|
||||
(tol==(int)tol) ? 0 : 3,
|
||||
tol,
|
||||
(val == (int) val) ? 0 : 3, val,
|
||||
(tol == (int) tol) ? 0 : 3, tol,
|
||||
unitstr);
|
||||
printf(" Status : %s\n", status ? : "");
|
||||
printf(" Status : %s\n",
|
||||
status ? : "");
|
||||
|
||||
if (thresh_available)
|
||||
{
|
||||
if (rsp->data[0] & LOWER_NON_RECOV_SPECIFIED)
|
||||
printf(" Lower Non-Recoverable : %.3f\n",
|
||||
sdr_convert_sensor_reading(sensor, rsp->data[3]));
|
||||
if (thresh_available) {
|
||||
if (rsp->
|
||||
data[0] & LOWER_NON_RECOV_SPECIFIED)
|
||||
printf
|
||||
(" Lower Non-Recoverable : %.3f\n",
|
||||
sdr_convert_sensor_reading
|
||||
(sensor, rsp->data[3]));
|
||||
else
|
||||
printf(" Lower Non-Recoverable : na\n");
|
||||
printf
|
||||
(" Lower Non-Recoverable : na\n");
|
||||
if (rsp->data[0] & LOWER_CRIT_SPECIFIED)
|
||||
printf(" Lower Critical : %.3f\n",
|
||||
sdr_convert_sensor_reading(sensor, rsp->data[2]));
|
||||
printf
|
||||
(" Lower Critical : %.3f\n",
|
||||
sdr_convert_sensor_reading
|
||||
(sensor, rsp->data[2]));
|
||||
else
|
||||
printf(" Lower Critical : na\n");
|
||||
if (rsp->data[0] & LOWER_NON_CRIT_SPECIFIED)
|
||||
printf(" Lower Non-Critical : %.3f\n",
|
||||
sdr_convert_sensor_reading(sensor, rsp->data[1]));
|
||||
printf
|
||||
(" Lower Critical : na\n");
|
||||
if (rsp->
|
||||
data[0] & LOWER_NON_CRIT_SPECIFIED)
|
||||
printf
|
||||
(" Lower Non-Critical : %.3f\n",
|
||||
sdr_convert_sensor_reading
|
||||
(sensor, rsp->data[1]));
|
||||
else
|
||||
printf(" Lower Non-Critical : na\n");
|
||||
if (rsp->data[0] & UPPER_NON_CRIT_SPECIFIED)
|
||||
printf(" Upper Non-Critical : %.3f\n",
|
||||
sdr_convert_sensor_reading(sensor, rsp->data[4]));
|
||||
printf
|
||||
(" Lower Non-Critical : na\n");
|
||||
if (rsp->
|
||||
data[0] & UPPER_NON_CRIT_SPECIFIED)
|
||||
printf
|
||||
(" Upper Non-Critical : %.3f\n",
|
||||
sdr_convert_sensor_reading
|
||||
(sensor, rsp->data[4]));
|
||||
else
|
||||
printf(" Upper Non-Critical : na\n");
|
||||
printf
|
||||
(" Upper Non-Critical : na\n");
|
||||
if (rsp->data[0] & UPPER_CRIT_SPECIFIED)
|
||||
printf(" Upper Critical : %.3f\n",
|
||||
sdr_convert_sensor_reading(sensor, rsp->data[5]));
|
||||
printf
|
||||
(" Upper Critical : %.3f\n",
|
||||
sdr_convert_sensor_reading
|
||||
(sensor, rsp->data[5]));
|
||||
else
|
||||
printf(" Upper Critical : na\n");
|
||||
if (rsp->data[0] & UPPER_NON_RECOV_SPECIFIED)
|
||||
printf(" Upper Non-Recoverable : %.3f\n",
|
||||
sdr_convert_sensor_reading(sensor, rsp->data[6]));
|
||||
printf
|
||||
(" Upper Critical : na\n");
|
||||
if (rsp->
|
||||
data[0] & UPPER_NON_RECOV_SPECIFIED)
|
||||
printf
|
||||
(" Upper Non-Recoverable : %.3f\n",
|
||||
sdr_convert_sensor_reading
|
||||
(sensor, rsp->data[6]));
|
||||
else
|
||||
printf(" Upper Non-Recoverable : na\n");
|
||||
printf
|
||||
(" Upper Non-Recoverable : na\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
printf("Not Present\n");
|
||||
}
|
||||
|
||||
ipmi_sdr_print_sensor_event_status(intf,
|
||||
sensor->keys.
|
||||
sensor_num,
|
||||
sensor->sensor.type,
|
||||
sensor->event_type,
|
||||
ANALOG_SENSOR);
|
||||
ipmi_sdr_print_sensor_event_enable(intf,
|
||||
sensor->keys.
|
||||
sensor_num,
|
||||
sensor->sensor.type,
|
||||
sensor->event_type,
|
||||
ANALOG_SENSOR);
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ipmi_sensor_print_full(struct ipmi_intf * intf,
|
||||
struct sdr_record_full_sensor * sensor)
|
||||
ipmi_sensor_print_full(struct ipmi_intf *intf,
|
||||
struct sdr_record_full_sensor *sensor)
|
||||
{
|
||||
if (sensor->unit.analog != 3)
|
||||
return ipmi_sensor_print_full_analog(intf, sensor);
|
||||
@ -378,25 +401,27 @@ ipmi_sensor_print_full(struct ipmi_intf * intf,
|
||||
}
|
||||
|
||||
int
|
||||
ipmi_sensor_print_compact(struct ipmi_intf * intf,
|
||||
struct sdr_record_compact_sensor * sensor)
|
||||
ipmi_sensor_print_compact(struct ipmi_intf *intf,
|
||||
struct sdr_record_compact_sensor *sensor)
|
||||
{
|
||||
char id[17];
|
||||
char * unitstr = "discrete";
|
||||
char *unitstr = "discrete";
|
||||
int validread = 1;
|
||||
uint8_t val = 0;
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rs *rsp;
|
||||
|
||||
if (sensor == NULL)
|
||||
return -1;
|
||||
|
||||
memset(id, 0, sizeof(id));
|
||||
memset(id, 0, sizeof (id));
|
||||
memcpy(id, sensor->id_string, 16);
|
||||
|
||||
/*
|
||||
* Get current reading
|
||||
*/
|
||||
rsp = ipmi_sdr_get_sensor_reading(intf, sensor->keys.sensor_num);
|
||||
rsp = ipmi_sdr_get_sensor_reading_ipmb(intf,
|
||||
sensor->keys.sensor_num,
|
||||
sensor->keys.owner_id);
|
||||
if (rsp == NULL) {
|
||||
lprintf(LOG_ERR, "Error reading sensor %s (#%02x)",
|
||||
id, sensor->keys.sensor_num);
|
||||
@ -408,14 +433,10 @@ ipmi_sensor_print_compact(struct ipmi_intf * intf,
|
||||
val = rsp->data[0];
|
||||
}
|
||||
|
||||
if (csv_output)
|
||||
{
|
||||
if (csv_output) {
|
||||
/* NOT IMPLEMENTED */
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!verbose)
|
||||
{
|
||||
} else {
|
||||
if (!verbose) {
|
||||
/* output format
|
||||
* id value units status thresholds....
|
||||
*/
|
||||
@ -433,16 +454,19 @@ ipmi_sensor_print_compact(struct ipmi_intf * intf,
|
||||
printf("| %-10s| %-10s| %-10s| %-10s| %-10s| %-10s",
|
||||
"na", "na", "na", "na", "na", "na");
|
||||
printf("\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
printf("Sensor ID : %s (0x%x)\n",
|
||||
id, sensor->keys.sensor_num);
|
||||
printf(" Entity ID : %d.%d\n",
|
||||
sensor->entity.id, sensor->entity.instance);
|
||||
printf(" Sensor Type (Discrete): %s\n",
|
||||
ipmi_sdr_get_sensor_type_desc(sensor->sensor.type));
|
||||
ipmi_sdr_print_discrete_state(sensor->sensor.type, sensor->event_type, rsp->data[2]);
|
||||
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");
|
||||
}
|
||||
}
|
||||
@ -451,10 +475,10 @@ ipmi_sensor_print_compact(struct ipmi_intf * intf,
|
||||
}
|
||||
|
||||
static int
|
||||
ipmi_sensor_list(struct ipmi_intf * intf)
|
||||
ipmi_sensor_list(struct ipmi_intf *intf)
|
||||
{
|
||||
struct sdr_get_rs * header;
|
||||
struct ipmi_sdr_iterator * itr;
|
||||
struct sdr_get_rs *header;
|
||||
struct ipmi_sdr_iterator *itr;
|
||||
int rc = 0;
|
||||
|
||||
lprintf(LOG_DEBUG, "Querying SDR for sensor list");
|
||||
@ -465,24 +489,28 @@ ipmi_sensor_list(struct ipmi_intf * intf)
|
||||
return -1;
|
||||
}
|
||||
|
||||
while ((header = ipmi_sdr_get_next_header(intf, itr)) != NULL)
|
||||
{
|
||||
while ((header = ipmi_sdr_get_next_header(intf, itr)) != NULL) {
|
||||
int r = 0;
|
||||
uint8_t * rec;
|
||||
uint8_t *rec;
|
||||
|
||||
rec = ipmi_sdr_get_record(intf, header, itr);
|
||||
if (rec == NULL)
|
||||
if (rec == NULL) {
|
||||
lprintf(LOG_DEBUG, "rec == NULL");
|
||||
continue;
|
||||
}
|
||||
|
||||
switch(header->type)
|
||||
{
|
||||
switch (header->type) {
|
||||
case SDR_RECORD_TYPE_FULL_SENSOR:
|
||||
r = ipmi_sensor_print_full(intf,
|
||||
(struct sdr_record_full_sensor *)rec);
|
||||
(struct
|
||||
sdr_record_full_sensor *)
|
||||
rec);
|
||||
break;
|
||||
case SDR_RECORD_TYPE_COMPACT_SENSOR:
|
||||
r = ipmi_sensor_print_compact(intf,
|
||||
(struct sdr_record_compact_sensor *)rec);
|
||||
(struct
|
||||
sdr_record_compact_sensor
|
||||
*) rec);
|
||||
break;
|
||||
}
|
||||
free(rec);
|
||||
@ -497,82 +525,22 @@ ipmi_sensor_list(struct ipmi_intf * intf)
|
||||
}
|
||||
|
||||
static const struct valstr threshold_vals[] = {
|
||||
{ UPPER_NON_RECOV_SPECIFIED, "Upper Non-Recoverable" },
|
||||
{ UPPER_CRIT_SPECIFIED, "Upper Critical" },
|
||||
{ UPPER_NON_CRIT_SPECIFIED, "Upper Non-Critical" },
|
||||
{ LOWER_NON_RECOV_SPECIFIED, "Lower Non-Recoverable" },
|
||||
{ LOWER_CRIT_SPECIFIED, "Lower Critical" },
|
||||
{ LOWER_NON_CRIT_SPECIFIED, "Lower Non-Critical" },
|
||||
{ 0x00, NULL },
|
||||
{UPPER_NON_RECOV_SPECIFIED, "Upper Non-Recoverable"},
|
||||
{UPPER_CRIT_SPECIFIED, "Upper Critical"},
|
||||
{UPPER_NON_CRIT_SPECIFIED, "Upper Non-Critical"},
|
||||
{LOWER_NON_RECOV_SPECIFIED, "Lower Non-Recoverable"},
|
||||
{LOWER_CRIT_SPECIFIED, "Lower Critical"},
|
||||
{LOWER_NON_CRIT_SPECIFIED, "Lower Non-Critical"},
|
||||
{0x00, NULL},
|
||||
};
|
||||
|
||||
static int
|
||||
ipmi_sensor_set_threshold(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
__ipmi_sensor_set_threshold(struct ipmi_intf *intf,
|
||||
uint8_t num, uint8_t mask, uint8_t setting)
|
||||
{
|
||||
char * id, * thresh;
|
||||
uint8_t settingMask;
|
||||
float setting;
|
||||
struct sdr_record_list * sdr;
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rs *rsp;
|
||||
|
||||
if (argc < 3 || strncmp(argv[0], "help", 4) == 0)
|
||||
{
|
||||
lprintf(LOG_NOTICE, "sensor thresh <id> <threshold> <setting>");
|
||||
lprintf(LOG_NOTICE, " id : name of the sensor for which threshold is to be set");
|
||||
lprintf(LOG_NOTICE, " threshold : which threshold to set");
|
||||
lprintf(LOG_NOTICE, " unr = upper non-recoverable");
|
||||
lprintf(LOG_NOTICE, " ucr = upper critical");
|
||||
lprintf(LOG_NOTICE, " unc = upper non-critical");
|
||||
lprintf(LOG_NOTICE, " lnc = lower non-critical");
|
||||
lprintf(LOG_NOTICE, " lcr = lower critical");
|
||||
lprintf(LOG_NOTICE, " lnr = lower non-recoverable");
|
||||
lprintf(LOG_NOTICE, " setting : the value to set the threshold to");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN);
|
||||
|
||||
id = argv[0];
|
||||
thresh = argv[1];
|
||||
setting = (float)atof(argv[2]);
|
||||
if (strncmp(thresh, "unr", 3) == 0)
|
||||
settingMask = UPPER_NON_RECOV_SPECIFIED;
|
||||
else if (strncmp(thresh, "ucr", 3) == 0)
|
||||
settingMask = UPPER_CRIT_SPECIFIED;
|
||||
else if (strncmp(thresh, "unc", 3) == 0)
|
||||
settingMask = UPPER_NON_CRIT_SPECIFIED;
|
||||
else if (strncmp(thresh, "lnc", 3) == 0)
|
||||
settingMask = LOWER_NON_CRIT_SPECIFIED;
|
||||
else if (strncmp(thresh, "lcr", 3) == 0)
|
||||
settingMask = LOWER_CRIT_SPECIFIED;
|
||||
else if (strncmp(thresh, "lnr", 3) == 0)
|
||||
settingMask = LOWER_NON_RECOV_SPECIFIED;
|
||||
else {
|
||||
lprintf(LOG_ERR, "Valid threshold not specified!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("Locating sensor record...\n");
|
||||
|
||||
/* lookup by sensor name */
|
||||
sdr = ipmi_sdr_find_sdr_byid(intf, id);
|
||||
if (sdr == NULL) {
|
||||
lprintf(LOG_ERR, "Sensor data record not found!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (sdr->type != SDR_RECORD_TYPE_FULL_SENSOR) {
|
||||
lprintf(LOG_ERR, "Invalid sensor type %02x", sdr->type);
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("Setting sensor \"%s\" %s threshold to %.3f\n",
|
||||
sdr->record.full->id_string,
|
||||
val2str(settingMask, threshold_vals), setting);
|
||||
|
||||
rsp = ipmi_sensor_set_sensor_thresholds(intf,
|
||||
sdr->record.full->keys.sensor_num, settingMask,
|
||||
sdr_convert_sensor_value_to_raw(sdr->record.full, setting));
|
||||
rsp = ipmi_sensor_set_sensor_thresholds(intf, num, mask, setting);
|
||||
|
||||
if (rsp == NULL) {
|
||||
lprintf(LOG_ERR, "Error setting threshold");
|
||||
@ -588,9 +556,185 @@ ipmi_sensor_set_threshold(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
}
|
||||
|
||||
static int
|
||||
ipmi_sensor_get(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
ipmi_sensor_set_threshold(struct ipmi_intf *intf, int argc, char **argv)
|
||||
{
|
||||
struct sdr_record_list * sdr;
|
||||
char *id, *thresh;
|
||||
uint8_t settingMask = 0;
|
||||
double setting1 = 0.0, setting2 = 0.0, setting3 = 0.0;
|
||||
int allUpper = 0, allLower = 0;
|
||||
int ret = 0;
|
||||
|
||||
struct sdr_record_list *sdr;
|
||||
|
||||
if (argc < 3 || strncmp(argv[0], "help", 4) == 0) {
|
||||
lprintf(LOG_NOTICE, "sensor thresh <id> <threshold> <setting>");
|
||||
lprintf(LOG_NOTICE,
|
||||
" id : name of the sensor for which threshold is to be set");
|
||||
lprintf(LOG_NOTICE, " threshold : which threshold to set");
|
||||
lprintf(LOG_NOTICE,
|
||||
" unr = upper non-recoverable");
|
||||
lprintf(LOG_NOTICE, " ucr = upper critical");
|
||||
lprintf(LOG_NOTICE,
|
||||
" unc = upper non-critical");
|
||||
lprintf(LOG_NOTICE,
|
||||
" lnc = lower non-critical");
|
||||
lprintf(LOG_NOTICE, " lcr = lower critical");
|
||||
lprintf(LOG_NOTICE,
|
||||
" lnr = lower non-recoverable");
|
||||
lprintf(LOG_NOTICE,
|
||||
" setting : the value to set the threshold to");
|
||||
lprintf(LOG_NOTICE, "");
|
||||
lprintf(LOG_NOTICE,
|
||||
"sensor thresh <id> lower <lnr> <lcr> <lnc>");
|
||||
lprintf(LOG_NOTICE,
|
||||
" Set all lower thresholds at the same time");
|
||||
lprintf(LOG_NOTICE, "");
|
||||
lprintf(LOG_NOTICE,
|
||||
"sensor thresh <id> upper <unc> <ucr> <unr>");
|
||||
lprintf(LOG_NOTICE,
|
||||
" Set all upper thresholds at the same time");
|
||||
lprintf(LOG_NOTICE, "");
|
||||
return 0;
|
||||
}
|
||||
|
||||
id = argv[0];
|
||||
thresh = argv[1];
|
||||
|
||||
if (strncmp(thresh, "upper", 5) == 0) {
|
||||
if (argc < 5) {
|
||||
lprintf(LOG_ERR,
|
||||
"usage: sensor thresh <id> upper <unc> <ucr> <unr>");
|
||||
return -1;
|
||||
}
|
||||
allUpper = 1;
|
||||
setting1 = (double) strtod(argv[2], NULL);
|
||||
setting2 = (double) strtod(argv[3], NULL);
|
||||
setting3 = (double) strtod(argv[4], NULL);
|
||||
} else if (strncmp(thresh, "lower", 5) == 0) {
|
||||
if (argc < 5) {
|
||||
lprintf(LOG_ERR,
|
||||
"usage: sensor thresh <id> lower <unc> <ucr> <unr>");
|
||||
return -1;
|
||||
}
|
||||
allLower = 1;
|
||||
setting1 = (double) strtod(argv[2], NULL);
|
||||
setting2 = (double) strtod(argv[3], NULL);
|
||||
setting3 = (double) strtod(argv[4], NULL);
|
||||
} else {
|
||||
setting1 = (double) atof(argv[2]);
|
||||
if (strncmp(thresh, "unr", 3) == 0)
|
||||
settingMask = UPPER_NON_RECOV_SPECIFIED;
|
||||
else if (strncmp(thresh, "ucr", 3) == 0)
|
||||
settingMask = UPPER_CRIT_SPECIFIED;
|
||||
else if (strncmp(thresh, "unc", 3) == 0)
|
||||
settingMask = UPPER_NON_CRIT_SPECIFIED;
|
||||
else if (strncmp(thresh, "lnc", 3) == 0)
|
||||
settingMask = LOWER_NON_CRIT_SPECIFIED;
|
||||
else if (strncmp(thresh, "lcr", 3) == 0)
|
||||
settingMask = LOWER_CRIT_SPECIFIED;
|
||||
else if (strncmp(thresh, "lnr", 3) == 0)
|
||||
settingMask = LOWER_NON_RECOV_SPECIFIED;
|
||||
else {
|
||||
lprintf(LOG_ERR,
|
||||
"Valid threshold '%s' for sensor '%s' not specified!",
|
||||
thresh, id);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
printf("Locating sensor record '%s'...\n", id);
|
||||
|
||||
/* lookup by sensor name */
|
||||
sdr = ipmi_sdr_find_sdr_byid(intf, id);
|
||||
if (sdr == NULL) {
|
||||
lprintf(LOG_ERR, "Sensor data record not found!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (sdr->type != SDR_RECORD_TYPE_FULL_SENSOR) {
|
||||
lprintf(LOG_ERR, "Invalid sensor type %02x", sdr->type);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (allUpper) {
|
||||
settingMask = UPPER_NON_CRIT_SPECIFIED;
|
||||
printf("Setting sensor \"%s\" %s threshold to %.3f\n",
|
||||
sdr->record.full->id_string,
|
||||
val2str(settingMask, threshold_vals), setting1);
|
||||
ret = __ipmi_sensor_set_threshold(intf,
|
||||
sdr->record.full->keys.
|
||||
sensor_num, settingMask,
|
||||
sdr_convert_sensor_value_to_raw
|
||||
(sdr->record.full, setting1));
|
||||
|
||||
settingMask = UPPER_CRIT_SPECIFIED;
|
||||
printf("Setting sensor \"%s\" %s threshold to %.3f\n",
|
||||
sdr->record.full->id_string,
|
||||
val2str(settingMask, threshold_vals), setting2);
|
||||
ret = __ipmi_sensor_set_threshold(intf,
|
||||
sdr->record.full->keys.
|
||||
sensor_num, settingMask,
|
||||
sdr_convert_sensor_value_to_raw
|
||||
(sdr->record.full, setting2));
|
||||
|
||||
settingMask = UPPER_NON_RECOV_SPECIFIED;
|
||||
printf("Setting sensor \"%s\" %s threshold to %.3f\n",
|
||||
sdr->record.full->id_string,
|
||||
val2str(settingMask, threshold_vals), setting3);
|
||||
ret = __ipmi_sensor_set_threshold(intf,
|
||||
sdr->record.full->keys.
|
||||
sensor_num, settingMask,
|
||||
sdr_convert_sensor_value_to_raw
|
||||
(sdr->record.full, setting3));
|
||||
} else if (allLower) {
|
||||
settingMask = LOWER_NON_RECOV_SPECIFIED;
|
||||
printf("Setting sensor \"%s\" %s threshold to %.3f\n",
|
||||
sdr->record.full->id_string,
|
||||
val2str(settingMask, threshold_vals), setting1);
|
||||
ret = __ipmi_sensor_set_threshold(intf,
|
||||
sdr->record.full->keys.
|
||||
sensor_num, settingMask,
|
||||
sdr_convert_sensor_value_to_raw
|
||||
(sdr->record.full, setting1));
|
||||
|
||||
settingMask = LOWER_CRIT_SPECIFIED;
|
||||
printf("Setting sensor \"%s\" %s threshold to %.3f\n",
|
||||
sdr->record.full->id_string,
|
||||
val2str(settingMask, threshold_vals), setting2);
|
||||
ret = __ipmi_sensor_set_threshold(intf,
|
||||
sdr->record.full->keys.
|
||||
sensor_num, settingMask,
|
||||
sdr_convert_sensor_value_to_raw
|
||||
(sdr->record.full, setting2));
|
||||
|
||||
settingMask = LOWER_NON_CRIT_SPECIFIED;
|
||||
printf("Setting sensor \"%s\" %s threshold to %.3f\n",
|
||||
sdr->record.full->id_string,
|
||||
val2str(settingMask, threshold_vals), setting3);
|
||||
ret = __ipmi_sensor_set_threshold(intf,
|
||||
sdr->record.full->keys.
|
||||
sensor_num, settingMask,
|
||||
sdr_convert_sensor_value_to_raw
|
||||
(sdr->record.full, setting3));
|
||||
} else {
|
||||
printf("Setting sensor \"%s\" %s threshold to %.3f\n",
|
||||
sdr->record.full->id_string,
|
||||
val2str(settingMask, threshold_vals), setting1);
|
||||
|
||||
ret = __ipmi_sensor_set_threshold(intf,
|
||||
sdr->record.full->keys.
|
||||
sensor_num, settingMask,
|
||||
sdr_convert_sensor_value_to_raw
|
||||
(sdr->record.full, setting1));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
ipmi_sensor_get(struct ipmi_intf *intf, int argc, char **argv)
|
||||
{
|
||||
struct sdr_record_list *sdr;
|
||||
int i, v;
|
||||
int rc = 0;
|
||||
|
||||
@ -602,7 +746,7 @@ ipmi_sensor_get(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
printf("Locating sensor record...\n");
|
||||
|
||||
/* lookup by sensor name */
|
||||
for (i=0; i<argc; i++) {
|
||||
for (i = 0; i < argc; i++) {
|
||||
int r = 0;
|
||||
|
||||
sdr = ipmi_sdr_find_sdr_byid(intf, argv[i]);
|
||||
@ -621,16 +765,22 @@ ipmi_sensor_get(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
r = ipmi_sensor_print_full(intf, sdr->record.full);
|
||||
break;
|
||||
case SDR_RECORD_TYPE_COMPACT_SENSOR:
|
||||
r = ipmi_sensor_print_compact(intf, sdr->record.compact);
|
||||
r = ipmi_sensor_print_compact(intf,
|
||||
sdr->record.compact);
|
||||
break;
|
||||
case SDR_RECORD_TYPE_EVENTONLY_SENSOR:
|
||||
r = ipmi_sdr_print_sensor_eventonly(intf, sdr->record.eventonly);
|
||||
r = ipmi_sdr_print_sensor_eventonly(intf,
|
||||
sdr->record.
|
||||
eventonly);
|
||||
break;
|
||||
case SDR_RECORD_TYPE_FRU_DEVICE_LOCATOR:
|
||||
r = ipmi_sdr_print_sensor_fru_locator(intf, sdr->record.fruloc);
|
||||
r = ipmi_sdr_print_sensor_fru_locator(intf,
|
||||
sdr->record.
|
||||
fruloc);
|
||||
break;
|
||||
case SDR_RECORD_TYPE_MC_DEVICE_LOCATOR:
|
||||
r = ipmi_sdr_print_sensor_mc_locator(intf, sdr->record.mcloc);
|
||||
r = ipmi_sdr_print_sensor_mc_locator(intf,
|
||||
sdr->record.mcloc);
|
||||
break;
|
||||
}
|
||||
verbose = v;
|
||||
@ -643,28 +793,22 @@ ipmi_sensor_get(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
}
|
||||
|
||||
int
|
||||
ipmi_sensor_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
ipmi_sensor_main(struct ipmi_intf *intf, int argc, char **argv)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (argc == 0) {
|
||||
rc = ipmi_sensor_list(intf);
|
||||
}
|
||||
else if (strncmp(argv[0], "help", 4) == 0) {
|
||||
} else if (strncmp(argv[0], "help", 4) == 0) {
|
||||
lprintf(LOG_NOTICE, "Sensor Commands: list thresh get");
|
||||
}
|
||||
else if (strncmp(argv[0], "list", 4) == 0) {
|
||||
} else if (strncmp(argv[0], "list", 4) == 0) {
|
||||
rc = ipmi_sensor_list(intf);
|
||||
}
|
||||
else if (strncmp(argv[0], "thresh", 5) == 0) {
|
||||
rc = ipmi_sensor_set_threshold(intf, argc-1, &argv[1]);
|
||||
}
|
||||
else if (strncmp(argv[0], "get", 3) == 0) {
|
||||
rc = ipmi_sensor_get(intf, argc-1, &argv[1]);
|
||||
}
|
||||
else {
|
||||
lprintf(LOG_ERR, "Invalid sensor command: %s",
|
||||
argv[0]);
|
||||
} else if (strncmp(argv[0], "thresh", 5) == 0) {
|
||||
rc = ipmi_sensor_set_threshold(intf, argc - 1, &argv[1]);
|
||||
} else if (strncmp(argv[0], "get", 3) == 0) {
|
||||
rc = ipmi_sensor_get(intf, argc - 1, &argv[1]);
|
||||
} else {
|
||||
lprintf(LOG_ERR, "Invalid sensor command: %s", argv[0]);
|
||||
rc = -1;
|
||||
}
|
||||
|
||||
|
@ -97,11 +97,19 @@ print_session_info_csv(const struct get_session_info_rsp * session_info,
|
||||
if (data_len == 18)
|
||||
{
|
||||
/* We have 802.3 LAN data */
|
||||
#ifdef __CYGWIN__
|
||||
printf(",%d.%d.%d.%d",
|
||||
session_info->channel_data.lan_data.console_ip[0],
|
||||
session_info->channel_data.lan_data.console_ip[1],
|
||||
session_info->channel_data.lan_data.console_ip[2],
|
||||
session_info->channel_data.lan_data.console_ip[3]);
|
||||
#else
|
||||
printf(",%s",
|
||||
inet_ntop(AF_INET,
|
||||
&(session_info->channel_data.lan_data.console_ip),
|
||||
buffer,
|
||||
16));
|
||||
#endif
|
||||
|
||||
printf(",%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
session_info->channel_data.lan_data.console_mac[0],
|
||||
@ -129,11 +137,19 @@ print_session_info_csv(const struct get_session_info_rsp * session_info,
|
||||
printf(",%d",
|
||||
session_info->channel_data.modem_data.destination_selector);
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
printf(",%d.%d.%d.%d",
|
||||
session_info->channel_data.modem_data.console_ip[0],
|
||||
session_info->channel_data.modem_data.console_ip[1],
|
||||
session_info->channel_data.modem_data.console_ip[2],
|
||||
session_info->channel_data.modem_data.console_ip[3]);
|
||||
#else
|
||||
printf(",%s",
|
||||
inet_ntop(AF_INET,
|
||||
&(session_info->channel_data.modem_data.console_ip),
|
||||
buffer,
|
||||
16));
|
||||
#endif
|
||||
|
||||
if (data_len == 14)
|
||||
{
|
||||
@ -185,11 +201,19 @@ print_session_info_verbose(const struct get_session_info_rsp * session_info,
|
||||
if (data_len == 18)
|
||||
{
|
||||
/* We have 802.3 LAN data */
|
||||
#ifdef __CYGWIN__
|
||||
printf("console ip : %d.%d.%d.%d\n",
|
||||
session_info->channel_data.lan_data.console_ip[0],
|
||||
session_info->channel_data.lan_data.console_ip[1],
|
||||
session_info->channel_data.lan_data.console_ip[2],
|
||||
session_info->channel_data.lan_data.console_ip[3]);
|
||||
#else
|
||||
printf("console ip : %s\n",
|
||||
inet_ntop(AF_INET,
|
||||
&(session_info->channel_data.lan_data.console_ip),
|
||||
buffer,
|
||||
16));
|
||||
#endif
|
||||
|
||||
printf("console mac : %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
session_info->channel_data.lan_data.console_mac[0],
|
||||
@ -217,11 +241,19 @@ print_session_info_verbose(const struct get_session_info_rsp * session_info,
|
||||
printf("Destination selector : %d\n",
|
||||
session_info->channel_data.modem_data.destination_selector);
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
printf("console ip : %d.%d.%d.%d\n",
|
||||
session_info->channel_data.modem_data.console_ip[0],
|
||||
session_info->channel_data.modem_data.console_ip[1],
|
||||
session_info->channel_data.modem_data.console_ip[2],
|
||||
session_info->channel_data.modem_data.console_ip[3]);
|
||||
#else
|
||||
printf("console ip : %s\n",
|
||||
inet_ntop(AF_INET,
|
||||
&(session_info->channel_data.modem_data.console_ip),
|
||||
buffer,
|
||||
16));
|
||||
#endif
|
||||
|
||||
if (data_len == 14)
|
||||
{
|
||||
@ -317,7 +349,7 @@ ipmi_get_session_info(struct ipmi_intf * intf,
|
||||
if (retval < 0)
|
||||
{
|
||||
if ((session_request_type == IPMI_SESSION_REQUEST_CURRENT) &&
|
||||
(strncmp(intf->name, "intf_lan", 8) != 0))
|
||||
(strncmp(intf->name, "lan", 3) != 0))
|
||||
lprintf(LOG_ERR, "It is likely that the channel in use "
|
||||
"does not support sessions");
|
||||
}
|
||||
@ -367,8 +399,8 @@ ipmi_get_session_info(struct ipmi_intf * intf,
|
||||
|
||||
|
||||
|
||||
void
|
||||
printf_session_usage()
|
||||
static void
|
||||
printf_session_usage(void)
|
||||
{
|
||||
lprintf(LOG_NOTICE, "Session Commands: info <active | all | id 0xnnnnnnnn | handle 0xnn>");
|
||||
}
|
||||
|
@ -36,8 +36,10 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/time.h>
|
||||
#include <signal.h>
|
||||
@ -65,7 +67,19 @@
|
||||
#define SOL_PARAMETER_SOL_PAYLOAD_CHANNEL 0x07
|
||||
#define SOL_PARAMETER_SOL_PAYLOAD_PORT 0x08
|
||||
|
||||
#define SOL_ESCAPE_CHARACTER '~'
|
||||
const struct valstr sol_parameter_vals[] = {
|
||||
{ SOL_PARAMETER_SET_IN_PROGRESS, "Set In Progress (0)" },
|
||||
{ SOL_PARAMETER_SOL_ENABLE, "Enable (1)" },
|
||||
{ SOL_PARAMETER_SOL_AUTHENTICATION, "Authentication (2)" },
|
||||
{ SOL_PARAMETER_CHARACTER_INTERVAL, "Character Interval (3)" },
|
||||
{ SOL_PARAMETER_SOL_RETRY, "Retry (4)" },
|
||||
{ SOL_PARAMETER_SOL_NON_VOLATILE_BIT_RATE, "Nonvolatile Bitrate (5)" },
|
||||
{ SOL_PARAMETER_SOL_VOLATILE_BIT_RATE, "Volatile Bitrate (6)" },
|
||||
{ SOL_PARAMETER_SOL_PAYLOAD_CHANNEL, "Payload Channel (7)" },
|
||||
{ SOL_PARAMETER_SOL_PAYLOAD_PORT, "Payload Port (8)" },
|
||||
{ 0x00, NULL },
|
||||
};
|
||||
|
||||
|
||||
static struct termios _saved_tio;
|
||||
static int _in_raw_mode = 0;
|
||||
@ -86,6 +100,7 @@ ipmi_get_sol_info(
|
||||
struct ipmi_rq req;
|
||||
uint8_t data[4];
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.msg.netfn = IPMI_NETFN_TRANSPORT;
|
||||
req.msg.cmd = IMPI_GET_SOL_CONFIG_PARAMETERS;
|
||||
req.msg.data_len = 4;
|
||||
@ -102,22 +117,33 @@ ipmi_get_sol_info(
|
||||
data[3] = 0x00; /* block selector */
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (!rsp || rsp->ccode) {
|
||||
lprintf(LOG_ERR, "Error:%x Error requesting SOL parameter %d",
|
||||
rsp ? rsp->ccode : 0,
|
||||
data[1]);
|
||||
return -1;
|
||||
}
|
||||
if (rsp->data_len != 2)
|
||||
{
|
||||
lprintf(LOG_ERR, "Error: Unexpected data length (%d) received "
|
||||
"for SOL paraemeter %d",
|
||||
rsp->data_len,
|
||||
data[1]);
|
||||
return -1;
|
||||
}
|
||||
params->set_in_progress = rsp->data[1];
|
||||
|
||||
if (NULL != rsp) {
|
||||
switch (rsp->ccode) {
|
||||
case 0x00:
|
||||
if (rsp->data_len == 2) {
|
||||
params->set_in_progress = rsp->data[1];
|
||||
} else {
|
||||
lprintf(LOG_ERR, "Error: Unexpected data length (%d) received "
|
||||
"for SOL parameter '%s'",
|
||||
rsp->data_len,
|
||||
val2str(data[1], sol_parameter_vals));
|
||||
}
|
||||
break;
|
||||
case 0x80:
|
||||
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(rsp->ccode, completion_code_vals));
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
lprintf(LOG_ERR, "Error: No response requesting SOL parameter '%s'",
|
||||
val2str(data[1], sol_parameter_vals));
|
||||
}
|
||||
|
||||
/*
|
||||
* SOL enable
|
||||
@ -129,22 +155,33 @@ ipmi_get_sol_info(
|
||||
data[3] = 0x00; /* block selector */
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (!rsp || rsp->ccode) {
|
||||
lprintf(LOG_ERR, "Error:%x Error requesting SOL parameter %d",
|
||||
rsp ? rsp->ccode : 0,
|
||||
data[1]);
|
||||
return -1;
|
||||
}
|
||||
if (rsp->data_len != 2)
|
||||
{
|
||||
lprintf(LOG_ERR, "Error: Unexpected data length (%d) received "
|
||||
"for SOL paraemeter %d",
|
||||
rsp->data_len,
|
||||
data[1]);
|
||||
return -1;
|
||||
}
|
||||
params->enabled = rsp->data[1];
|
||||
|
||||
if (NULL != rsp) {
|
||||
switch (rsp->ccode) {
|
||||
case 0x00:
|
||||
if (rsp->data_len == 2) {
|
||||
params->enabled = rsp->data[1];
|
||||
} else {
|
||||
lprintf(LOG_ERR, "Error: Unexpected data length (%d) received "
|
||||
"for SOL parameter '%s'",
|
||||
rsp->data_len,
|
||||
val2str(data[1], sol_parameter_vals));
|
||||
}
|
||||
break;
|
||||
case 0x80:
|
||||
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(rsp->ccode, completion_code_vals));
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
lprintf(LOG_ERR, "Error: No response requesting SOL parameter '%s'",
|
||||
val2str(data[1], sol_parameter_vals));
|
||||
}
|
||||
|
||||
/*
|
||||
* SOL authentication
|
||||
@ -156,24 +193,34 @@ ipmi_get_sol_info(
|
||||
data[3] = 0x00; /* block selector */
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (!rsp || rsp->ccode) {
|
||||
lprintf(LOG_ERR, "Error:%x Error requesting SOL parameter %d",
|
||||
rsp ? rsp->ccode : 0,
|
||||
data[1]);
|
||||
return -1;
|
||||
}
|
||||
if (rsp->data_len != 2)
|
||||
{
|
||||
lprintf(LOG_ERR, "Error: Unexpected data length (%d) received "
|
||||
"for SOL paraemeter %d",
|
||||
rsp->data_len,
|
||||
data[1]);
|
||||
return -1;
|
||||
}
|
||||
if (NULL != rsp) {
|
||||
switch (rsp->ccode) {
|
||||
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);
|
||||
params->privilege_level = rsp->data[1] & 0x0F;
|
||||
|
||||
} else {
|
||||
lprintf(LOG_ERR, "Error: Unexpected data length (%d) received "
|
||||
"for SOL parameter '%s'",
|
||||
rsp->data_len,
|
||||
val2str(data[1], sol_parameter_vals));
|
||||
}
|
||||
break;
|
||||
case 0x80:
|
||||
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(rsp->ccode, completion_code_vals));
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
lprintf(LOG_ERR, "Error: No response requesting SOL parameter '%s'",
|
||||
val2str(data[1], sol_parameter_vals));
|
||||
}
|
||||
|
||||
/*
|
||||
* Character accumulate interval and character send interval
|
||||
@ -185,23 +232,33 @@ ipmi_get_sol_info(
|
||||
data[3] = 0x00; /* block selector */
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (!rsp || rsp->ccode) {
|
||||
lprintf(LOG_ERR, "Error:%x Error requesting SOL parameter %d",
|
||||
rsp ? rsp->ccode : 0,
|
||||
data[1]);
|
||||
return -1;
|
||||
}
|
||||
if (rsp->data_len != 3)
|
||||
{
|
||||
lprintf(LOG_ERR, "Error: Unexpected data length (%d) received "
|
||||
"for SOL paraemeter %d",
|
||||
rsp->data_len,
|
||||
data[1]);
|
||||
return -1;
|
||||
}
|
||||
if (NULL != rsp) {
|
||||
switch (rsp->ccode) {
|
||||
case 0x00:
|
||||
if (rsp->data_len == 3) {
|
||||
params->character_accumulate_level = rsp->data[1];
|
||||
params->character_send_threshold = rsp->data[2];
|
||||
|
||||
} else {
|
||||
lprintf(LOG_ERR, "Error: Unexpected data length (%d) received "
|
||||
"for SOL parameter '%s'",
|
||||
rsp->data_len,
|
||||
val2str(data[1], sol_parameter_vals));
|
||||
}
|
||||
break;
|
||||
case 0x80:
|
||||
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(rsp->ccode, completion_code_vals));
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
lprintf(LOG_ERR, "Error: No response requesting SOL parameter '%s'",
|
||||
val2str(data[1], sol_parameter_vals));
|
||||
}
|
||||
|
||||
/*
|
||||
* SOL retry
|
||||
@ -213,23 +270,33 @@ ipmi_get_sol_info(
|
||||
data[3] = 0x00; /* block selector */
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (!rsp || rsp->ccode) {
|
||||
lprintf(LOG_ERR, "Error:%x Error requesting SOL parameter %d",
|
||||
rsp ? rsp->ccode : 0,
|
||||
data[1]);
|
||||
return -1;
|
||||
}
|
||||
if (rsp->data_len != 3)
|
||||
{
|
||||
lprintf(LOG_ERR, "Error: Unexpected data length (%d) received "
|
||||
"for SOL paraemeter %d",
|
||||
rsp->data_len,
|
||||
data[1]);
|
||||
return -1;
|
||||
}
|
||||
if (NULL != rsp) {
|
||||
switch (rsp->ccode) {
|
||||
case 0x00:
|
||||
if (rsp->data_len == 3) {
|
||||
params->retry_count = rsp->data[1];
|
||||
params->retry_interval = rsp->data[2];
|
||||
|
||||
} else {
|
||||
lprintf(LOG_ERR, "Error: Unexpected data length (%d) received "
|
||||
"for SOL parameter '%s'",
|
||||
rsp->data_len,
|
||||
val2str(data[1], sol_parameter_vals));
|
||||
}
|
||||
break;
|
||||
case 0x80:
|
||||
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(rsp->ccode, completion_code_vals));
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
lprintf(LOG_ERR, "Error: No response requesting SOL parameter '%s'",
|
||||
val2str(data[1], sol_parameter_vals));
|
||||
}
|
||||
|
||||
/*
|
||||
* SOL non-volatile bit rate
|
||||
@ -241,22 +308,32 @@ ipmi_get_sol_info(
|
||||
data[3] = 0x00; /* block selector */
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (!rsp || rsp->ccode) {
|
||||
lprintf(LOG_ERR, "Error:%x Error requesting SOL parameter %d",
|
||||
rsp ? rsp->ccode : 0,
|
||||
data[1]);
|
||||
return -1;
|
||||
}
|
||||
if (rsp->data_len != 2)
|
||||
{
|
||||
lprintf(LOG_ERR, "Error: Unexpected data length (%d) received "
|
||||
"for SOL paraemeter %d",
|
||||
rsp->data_len,
|
||||
data[1]);
|
||||
return -1;
|
||||
}
|
||||
if (NULL != rsp) {
|
||||
switch (rsp->ccode) {
|
||||
case 0x00:
|
||||
if (rsp->data_len == 2) {
|
||||
params->non_volatile_bit_rate = rsp->data[1] & 0x0F;
|
||||
|
||||
} else {
|
||||
lprintf(LOG_ERR, "Error: Unexpected data length (%d) received "
|
||||
"for SOL parameter '%s'",
|
||||
rsp->data_len,
|
||||
val2str(data[1], sol_parameter_vals));
|
||||
}
|
||||
break;
|
||||
case 0x80:
|
||||
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(rsp->ccode, completion_code_vals));
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
lprintf(LOG_ERR, "Error: No response requesting SOL parameter '%s'",
|
||||
val2str(data[1], sol_parameter_vals));
|
||||
}
|
||||
|
||||
/*
|
||||
* SOL volatile bit rate
|
||||
@ -268,22 +345,32 @@ ipmi_get_sol_info(
|
||||
data[3] = 0x00; /* block selector */
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (!rsp || rsp->ccode) {
|
||||
lprintf(LOG_ERR, "Error:%x Error requesting SOL parameter %d",
|
||||
rsp ? rsp->ccode : 0,
|
||||
data[1]);
|
||||
return -1;
|
||||
}
|
||||
if (rsp->data_len != 2)
|
||||
{
|
||||
lprintf(LOG_ERR, "Error: Unexpected data length (%d) received "
|
||||
"for SOL paraemeter %d",
|
||||
rsp->data_len,
|
||||
data[1]);
|
||||
return -1;
|
||||
}
|
||||
if (NULL != rsp) {
|
||||
switch (rsp->ccode) {
|
||||
case 0x00:
|
||||
if (rsp->data_len == 2) {
|
||||
params->volatile_bit_rate = rsp->data[1] & 0x0F;
|
||||
|
||||
} else {
|
||||
lprintf(LOG_ERR, "Error: Unexpected data length (%d) received "
|
||||
"for SOL parameter '%s'",
|
||||
rsp->data_len,
|
||||
val2str(data[1], sol_parameter_vals));
|
||||
}
|
||||
break;
|
||||
case 0x80:
|
||||
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(rsp->ccode, completion_code_vals));
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
lprintf(LOG_ERR, "Error: No response requesting SOL parameter '%s'",
|
||||
val2str(data[1], sol_parameter_vals));
|
||||
}
|
||||
|
||||
/*
|
||||
* SOL payload channel
|
||||
@ -295,22 +382,33 @@ ipmi_get_sol_info(
|
||||
data[3] = 0x00; /* block selector */
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (!rsp || rsp->ccode) {
|
||||
lprintf(LOG_ERR, "Error:%x Error requesting SOL parameter %d",
|
||||
rsp ? rsp->ccode : 0,
|
||||
data[1]);
|
||||
return -1;
|
||||
}
|
||||
if (rsp->data_len != 2)
|
||||
{
|
||||
lprintf(LOG_ERR, "Error: Unexpected data length (%d) received "
|
||||
"for SOL paraemeter %d",
|
||||
rsp->data_len,
|
||||
data[1]);
|
||||
return -1;
|
||||
}
|
||||
if (NULL != rsp) {
|
||||
switch (rsp->ccode) {
|
||||
case 0x00:
|
||||
if (rsp->data_len == 2) {
|
||||
params->payload_channel = rsp->data[1];
|
||||
|
||||
} else {
|
||||
lprintf(LOG_ERR, "Error: Unexpected data length (%d) received "
|
||||
"for SOL parameter '%s'",
|
||||
rsp->data_len,
|
||||
val2str(data[1], sol_parameter_vals));
|
||||
}
|
||||
break;
|
||||
case 0x80:
|
||||
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;
|
||||
default:
|
||||
lprintf(LOG_ERR, "Error requesting SOL parameter '%s': %s",
|
||||
val2str(data[1], sol_parameter_vals),
|
||||
val2str(rsp->ccode, completion_code_vals));
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
lprintf(LOG_ERR, "Error: No response requesting SOL parameter '%s'",
|
||||
val2str(data[1], sol_parameter_vals));
|
||||
}
|
||||
|
||||
/*
|
||||
* SOL payload port
|
||||
@ -322,21 +420,33 @@ ipmi_get_sol_info(
|
||||
data[3] = 0x00; /* block selector */
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (!rsp || rsp->ccode) {
|
||||
lprintf(LOG_ERR, "Error:%x Error requesting SOL parameter %d",
|
||||
rsp ? rsp->ccode : 0,
|
||||
data[1]);
|
||||
return -1;
|
||||
}
|
||||
if (rsp->data_len != 3)
|
||||
{
|
||||
lprintf(LOG_ERR, "Error: Unexpected data length (%d) "
|
||||
"received for SOL paraemeter %d",
|
||||
rsp->data_len,
|
||||
data[1]);
|
||||
return -1;
|
||||
}
|
||||
if (NULL != rsp) {
|
||||
switch (rsp->ccode) {
|
||||
case 0x00:
|
||||
if (rsp->data_len == 3) {
|
||||
params->payload_port = (rsp->data[1]) | (rsp->data[2] << 8);
|
||||
} else {
|
||||
lprintf(LOG_ERR, "Error: Unexpected data length (%d) received "
|
||||
"for SOL parameter '%s'",
|
||||
rsp->data_len,
|
||||
val2str(data[1], sol_parameter_vals));
|
||||
}
|
||||
break;
|
||||
case 0x80:
|
||||
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;
|
||||
default:
|
||||
lprintf(LOG_ERR, "Error requesting SOL parameter '%s': %s",
|
||||
val2str(data[1], sol_parameter_vals),
|
||||
val2str(rsp->ccode, completion_code_vals));
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
lprintf(LOG_ERR, "Error: No response requesting SOL parameter '%s'",
|
||||
val2str(data[1], sol_parameter_vals));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -349,7 +459,7 @@ ipmi_get_sol_info(
|
||||
static int
|
||||
ipmi_print_sol_info(struct ipmi_intf * intf, uint8_t channel)
|
||||
{
|
||||
struct sol_config_parameters params;
|
||||
struct sol_config_parameters params = {0};
|
||||
if (ipmi_get_sol_info(intf, channel, ¶ms))
|
||||
return -1;
|
||||
|
||||
@ -405,8 +515,8 @@ ipmi_print_sol_info(struct ipmi_intf * intf, uint8_t channel)
|
||||
printf("Non-Volatile Bit Rate (kbps) : %s\n",
|
||||
val2str(params.non_volatile_bit_rate, impi_bit_rate_vals));
|
||||
|
||||
printf("Payload Channel : %d\n",
|
||||
params.payload_channel);
|
||||
printf("Payload Channel : %d (0x%02x)\n",
|
||||
params.payload_channel, params.payload_channel);
|
||||
printf("Payload Port : %d\n",
|
||||
params.payload_port);
|
||||
}
|
||||
@ -436,6 +546,7 @@ ipmi_sol_set_param(struct ipmi_intf * intf,
|
||||
uint8_t data[4];
|
||||
int bGuarded = 1; /* Use set-in-progress indicator? */
|
||||
|
||||
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;
|
||||
@ -658,7 +769,7 @@ ipmi_sol_set_param(struct ipmi_intf * intf,
|
||||
|
||||
req.msg.data_len = 4;
|
||||
data[1] = SOL_PARAMETER_SOL_RETRY;
|
||||
data[2] = (uint8_t)strtol(value, NULL, 0) & 0x03;
|
||||
data[2] = (uint8_t)strtol(value, NULL, 0) & 0x07;
|
||||
|
||||
/* We need other values to complete the request */
|
||||
if (ipmi_get_sol_info(intf, channel, ¶ms))
|
||||
@ -804,11 +915,14 @@ ipmi_sol_set_param(struct ipmi_intf * intf,
|
||||
/* The command proper */
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
|
||||
if (rsp == NULL) {
|
||||
lprintf(LOG_ERR, "Error setting SOL parameter '%s'", param);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!rsp || rsp->ccode) {
|
||||
lprintf(LOG_ERR, "Error:%x Error setting SOL parameter %s",
|
||||
rsp ? rsp->ccode : 0,
|
||||
param);
|
||||
if (rsp->ccode > 0) {
|
||||
lprintf(LOG_ERR, "Error setting SOL parameter '%s': %s",
|
||||
param, val2str(rsp->ccode, completion_code_vals));
|
||||
|
||||
if (bGuarded &&
|
||||
(ipmi_sol_set_param(intf,
|
||||
@ -931,8 +1045,8 @@ suspendSelf(int bRestoreTty)
|
||||
*
|
||||
* Send some useful documentation to the user
|
||||
*/
|
||||
void
|
||||
printSolEscapeSequences()
|
||||
static void
|
||||
printSolEscapeSequences(struct ipmi_intf * intf)
|
||||
{
|
||||
printf(
|
||||
"%c?\r\n\
|
||||
@ -944,14 +1058,14 @@ printSolEscapeSequences()
|
||||
%c? - this message\r\n\
|
||||
%c%c - send the escape character by typing it twice\r\n\
|
||||
(Note that escapes are only recognized immediately after newline.)\r\n",
|
||||
SOL_ESCAPE_CHARACTER,
|
||||
SOL_ESCAPE_CHARACTER,
|
||||
SOL_ESCAPE_CHARACTER,
|
||||
SOL_ESCAPE_CHARACTER,
|
||||
SOL_ESCAPE_CHARACTER,
|
||||
SOL_ESCAPE_CHARACTER,
|
||||
SOL_ESCAPE_CHARACTER,
|
||||
SOL_ESCAPE_CHARACTER);
|
||||
intf->session->sol_escape_char,
|
||||
intf->session->sol_escape_char,
|
||||
intf->session->sol_escape_char,
|
||||
intf->session->sol_escape_char,
|
||||
intf->session->sol_escape_char,
|
||||
intf->session->sol_escape_char,
|
||||
intf->session->sol_escape_char,
|
||||
intf->session->sol_escape_char);
|
||||
}
|
||||
|
||||
|
||||
@ -986,6 +1100,7 @@ ipmi_sol_deactivate(struct ipmi_intf * intf)
|
||||
struct ipmi_rq req;
|
||||
uint8_t data[6];
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.msg.netfn = IPMI_NETFN_APP;
|
||||
req.msg.cmd = IPMI_DEACTIVATE_PAYLOAD;
|
||||
req.msg.data_len = 6;
|
||||
@ -1003,13 +1118,26 @@ ipmi_sol_deactivate(struct ipmi_intf * intf)
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
|
||||
if (!rsp || rsp->ccode) {
|
||||
lprintf(LOG_ERR, "Error:%x Dectivating SOL payload",
|
||||
rsp ? rsp->ccode : 0);
|
||||
return -1;
|
||||
if (NULL != rsp) {
|
||||
switch (rsp->ccode) {
|
||||
case 0x00:
|
||||
return 0;
|
||||
case 0x80:
|
||||
lprintf(LOG_ERR, "Info: SOL payload already de-activated");
|
||||
break;
|
||||
case 0x81:
|
||||
lprintf(LOG_ERR, "Info: SOL payload type disabled");
|
||||
break;
|
||||
default:
|
||||
lprintf(LOG_ERR, "Error de-activating SOL payload: %s",
|
||||
val2str(rsp->ccode, completion_code_vals));
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
lprintf(LOG_ERR, "Error: No response de-activating SOL payload");
|
||||
}
|
||||
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@ -1056,38 +1184,44 @@ processSolUserInput(
|
||||
*/
|
||||
switch (ch) {
|
||||
case '.':
|
||||
printf("%c. [terminated ipmitool]\r\n", SOL_ESCAPE_CHARACTER);
|
||||
printf("%c. [terminated ipmitool]\r\n",
|
||||
intf->session->sol_escape_char);
|
||||
retval = 1;
|
||||
break;
|
||||
|
||||
case 'Z' - 64:
|
||||
printf("%c^Z [suspend ipmitool]\r\n", SOL_ESCAPE_CHARACTER);
|
||||
printf("%c^Z [suspend ipmitool]\r\n",
|
||||
intf->session->sol_escape_char);
|
||||
suspendSelf(1); /* Restore tty back to raw */
|
||||
continue;
|
||||
|
||||
case 'X' - 64:
|
||||
printf("%c^Z [suspend ipmitool]\r\n", SOL_ESCAPE_CHARACTER);
|
||||
printf("%c^Z [suspend ipmitool]\r\n",
|
||||
intf->session->sol_escape_char);
|
||||
suspendSelf(0); /* Don't restore to raw mode */
|
||||
continue;
|
||||
|
||||
case 'B':
|
||||
printf("%cb [send break]\r\n", SOL_ESCAPE_CHARACTER);
|
||||
printf("%cb [send break]\r\n",
|
||||
intf->session->sol_escape_char);
|
||||
sendBreak(intf);
|
||||
continue;
|
||||
|
||||
case '?':
|
||||
printSolEscapeSequences();
|
||||
printSolEscapeSequences(intf);
|
||||
continue;
|
||||
|
||||
default:
|
||||
if (ch != SOL_ESCAPE_CHARACTER)
|
||||
if (ch != intf->session->sol_escape_char)
|
||||
v2_payload.payload.sol_packet.data[length++] =
|
||||
SOL_ESCAPE_CHARACTER;
|
||||
intf->session->sol_escape_char;
|
||||
v2_payload.payload.sol_packet.data[length++] = ch;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
if (last_was_cr && (ch == SOL_ESCAPE_CHARACTER)) {
|
||||
if (last_was_cr && (ch == intf->session->sol_escape_char)) {
|
||||
escape_pending = 1;
|
||||
continue;
|
||||
}
|
||||
@ -1283,6 +1417,7 @@ ipmi_sol_activate(struct ipmi_intf * intf)
|
||||
intf->session->sol_data.sol_input_handler = output;
|
||||
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.msg.netfn = IPMI_NETFN_APP;
|
||||
req.msg.cmd = IPMI_ACTIVATE_PAYLOAD;
|
||||
req.msg.data_len = 6;
|
||||
@ -1303,18 +1438,43 @@ ipmi_sol_activate(struct ipmi_intf * intf)
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
|
||||
if (!rsp || rsp->ccode) {
|
||||
lprintf(LOG_ERR, "Error:%x Activating SOL payload",
|
||||
rsp ? rsp->ccode : 0);
|
||||
return -1;
|
||||
}
|
||||
if (rsp->data_len != 12)
|
||||
{
|
||||
if (NULL != rsp) {
|
||||
switch (rsp->ccode) {
|
||||
case 0x00:
|
||||
if (rsp->data_len == 12) {
|
||||
break;
|
||||
} else {
|
||||
lprintf(LOG_ERR, "Error: Unexpected data length (%d) received "
|
||||
"in payload activation response",
|
||||
rsp->data_len);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case 0x80:
|
||||
lprintf(LOG_ERR, "Info: SOL payload already active on another session");
|
||||
return -1;
|
||||
case 0x81:
|
||||
lprintf(LOG_ERR, "Info: SOL payload disabled");
|
||||
return -1;
|
||||
case 0x82:
|
||||
lprintf(LOG_ERR, "Info: SOL payload activation limit reached");
|
||||
return -1;
|
||||
case 0x83:
|
||||
lprintf(LOG_ERR, "Info: cannot activate SOL payload with encryption");
|
||||
return -1;
|
||||
case 0x84:
|
||||
lprintf(LOG_ERR, "Info: cannot activate SOL payload without encryption");
|
||||
return -1;
|
||||
default:
|
||||
lprintf(LOG_ERR, "Error activating SOL payload: %s",
|
||||
val2str(rsp->ccode, completion_code_vals));
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
lprintf(LOG_ERR, "Error: No response activating SOL payload");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
memcpy(&ap_rsp, rsp->data, sizeof(struct activate_payload_rsp));
|
||||
|
||||
@ -1345,15 +1505,25 @@ ipmi_sol_activate(struct ipmi_intf * intf)
|
||||
intf->session->timeout = 3;
|
||||
|
||||
|
||||
/* NOTE: the spec does allow for SOL traffic to be sent on
|
||||
* a different port. we do not yet support that feature. */
|
||||
if (intf->session->sol_data.port != intf->session->port)
|
||||
{
|
||||
/* try byteswapping port in case BMC sent it incorrectly */
|
||||
uint16_t portswap = BSWAP_16(intf->session->sol_data.port);
|
||||
|
||||
if (portswap == intf->session->port) {
|
||||
intf->session->sol_data.port = portswap;
|
||||
}
|
||||
else {
|
||||
lprintf(LOG_ERR, "Error: BMC requests SOL session on different port");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
printf("[SOL Session operational. Use %c? for help]\r\n",
|
||||
SOL_ESCAPE_CHARACTER);
|
||||
intf->session->sol_escape_char);
|
||||
|
||||
|
||||
/*
|
||||
@ -1376,8 +1546,8 @@ ipmi_sol_activate(struct ipmi_intf * intf)
|
||||
/*
|
||||
* print_sol_usage
|
||||
*/
|
||||
void
|
||||
print_sol_usage()
|
||||
static void
|
||||
print_sol_usage(void)
|
||||
{
|
||||
lprintf(LOG_NOTICE, "SOL Commands: info [<channel number>]");
|
||||
lprintf(LOG_NOTICE, " set <parameter> <value> [channel]");
|
||||
@ -1390,8 +1560,8 @@ print_sol_usage()
|
||||
/*
|
||||
* print_sol_set_usage
|
||||
*/
|
||||
void
|
||||
print_sol_set_usage()
|
||||
static void
|
||||
print_sol_set_usage(void)
|
||||
{
|
||||
lprintf(LOG_NOTICE, "\nSOL set parameters and values: \n");
|
||||
lprintf(LOG_NOTICE, " set-in-progress set-complete | "
|
||||
|
@ -38,7 +38,30 @@
|
||||
#include <ipmitool/ipmi_strings.h>
|
||||
#include <ipmitool/ipmi_constants.h>
|
||||
#include <ipmitool/ipmi_sensor.h>
|
||||
#include <ipmitool/ipmi_sel.h> /* for IPMI_OEM */
|
||||
|
||||
const struct valstr ipmi_oem_info[] = {
|
||||
|
||||
{ IPMI_OEM_UNKNOWN, "Unknown" },
|
||||
{ IPMI_OEM_SUN, "Sun Microsystems" },
|
||||
{ IPMI_OEM_INTEL, "Intel Corporation" },
|
||||
{ IPMI_OEM_TYAN, "Tyan Computer Corporation" },
|
||||
{ IPMI_OEM_NEWISYS, "Newisys" },
|
||||
{ IPMI_OEM_SUPERMICRO, "Supermicro" },
|
||||
{ IPMI_OEM_KONTRON, "Kontron" },
|
||||
{ 0xffff , NULL },
|
||||
};
|
||||
|
||||
const struct valstr ipmi_netfn_vals[] = {
|
||||
{ IPMI_NETFN_CHASSIS, "Chassis" },
|
||||
{ IPMI_NETFN_BRIDGE, "Bridge" },
|
||||
{ IPMI_NETFN_SE, "SensorEvent" },
|
||||
{ IPMI_NETFN_APP, "Application" },
|
||||
{ IPMI_NETFN_FIRMWARE, "Firmware" },
|
||||
{ IPMI_NETFN_STORAGE, "Storage" },
|
||||
{ IPMI_NETFN_TRANSPORT, "Transport" },
|
||||
{ 0xff, NULL },
|
||||
};
|
||||
|
||||
/*
|
||||
* From table 26-4 of the IPMI v2 specification
|
||||
@ -69,7 +92,7 @@ const struct valstr ipmi_privlvl_vals[] = {
|
||||
{ IPMI_SESSION_PRIV_ADMIN, "ADMINISTRATOR" },
|
||||
{ IPMI_SESSION_PRIV_OEM, "OEM" },
|
||||
{ 0xF, "NO ACCESS" },
|
||||
{ 0, NULL },
|
||||
{ 0xFF, NULL },
|
||||
};
|
||||
|
||||
|
||||
@ -87,7 +110,7 @@ const struct valstr ipmi_authtype_session_vals[] = {
|
||||
{ IPMI_SESSION_AUTHTYPE_MD5, "MD5" },
|
||||
{ IPMI_SESSION_AUTHTYPE_PASSWORD, "PASSWORD" },
|
||||
{ IPMI_SESSION_AUTHTYPE_OEM, "OEM" },
|
||||
{ 0, NULL },
|
||||
{ 0xFF, NULL },
|
||||
};
|
||||
|
||||
|
||||
@ -142,6 +165,18 @@ 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" },
|
||||
{ 0x00, NULL },
|
||||
};
|
||||
|
||||
@ -211,7 +246,7 @@ const struct valstr ipmi_channel_protocol_vals[] = {
|
||||
|
||||
const struct valstr ipmi_channel_medium_vals[] = {
|
||||
{ IPMI_CHANNEL_MEDIUM_RESERVED, "reserved" },
|
||||
{ IPMI_CHANNEL_MEDIUM_IPMB, "IPMB (I2C)" },
|
||||
{ IPMI_CHANNEL_MEDIUM_IPMB_I2C, "IPMB (I2C)" },
|
||||
{ IPMI_CHANNEL_MEDIUM_ICMB_1, "ICMB v1.0" },
|
||||
{ IPMI_CHANNEL_MEDIUM_ICMB_09, "ICMB v0.9" },
|
||||
{ IPMI_CHANNEL_MEDIUM_LAN, "802.3 LAN" },
|
||||
@ -254,3 +289,35 @@ const struct valstr completion_code_vals[] = {
|
||||
{ 0x00, NULL }
|
||||
};
|
||||
|
||||
const struct valstr ipmi_chassis_power_control_vals[] = {
|
||||
{ IPMI_CHASSIS_CTL_POWER_DOWN, "Down/Off" },
|
||||
{ IPMI_CHASSIS_CTL_POWER_UP, "Up/On" },
|
||||
{ IPMI_CHASSIS_CTL_POWER_CYCLE, "Cycle" },
|
||||
{ IPMI_CHASSIS_CTL_HARD_RESET, "Reset" },
|
||||
{ IPMI_CHASSIS_CTL_PULSE_DIAG, "Diag" },
|
||||
{ IPMI_CHASSIS_CTL_ACPI_SOFT, "Soft" },
|
||||
{ 0x00, NULL },
|
||||
};
|
||||
|
||||
const struct valstr ipmi_auth_algorithms[] = {
|
||||
{ IPMI_AUTH_RAKP_NONE, "none" },
|
||||
{ IPMI_AUTH_RAKP_HMAC_SHA1, "hmac_sha1" },
|
||||
{ IPMI_AUTH_RAKP_HMAC_MD5, "hmac_md5" },
|
||||
{ 0x00, NULL }
|
||||
};
|
||||
|
||||
const struct valstr ipmi_integrity_algorithms[] = {
|
||||
{ IPMI_INTEGRITY_NONE, "none" },
|
||||
{ IPMI_INTEGRITY_HMAC_SHA1_96, "hmac_sha1_96" },
|
||||
{ IPMI_INTEGRITY_HMAC_MD5_128, "hmac_md5_128" },
|
||||
{ IPMI_INTEGRITY_MD5_128 , "md5_128" },
|
||||
{ 0x00, NULL }
|
||||
};
|
||||
|
||||
const struct valstr ipmi_encryption_algorithms[] = {
|
||||
{ IPMI_CRYPT_NONE, "none" },
|
||||
{ IPMI_CRYPT_AES_CBC_128, "aes_cbc_128" },
|
||||
{ IPMI_CRYPT_XRC4_128, "xrc4_128" },
|
||||
{ IPMI_CRYPT_XRC4_40, "xrc4_40" },
|
||||
{ 0x00, NULL }
|
||||
};
|
||||
|
794
ipmitool/lib/ipmi_sunoem.c
Normal file
794
ipmitool/lib/ipmi_sunoem.c
Normal file
@ -0,0 +1,794 @@
|
||||
/*
|
||||
* Copyright (c) 2005 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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <ipmitool/ipmi.h>
|
||||
#include <ipmitool/ipmi_intf.h>
|
||||
#include <ipmitool/helper.h>
|
||||
#include <ipmitool/log.h>
|
||||
#include <ipmitool/ipmi_sel.h>
|
||||
#include <ipmitool/ipmi_sdr.h>
|
||||
#include <ipmitool/ipmi_strings.h>
|
||||
#include <ipmitool/ipmi_channel.h>
|
||||
#include <ipmitool/ipmi_sunoem.h>
|
||||
#include <ipmitool/ipmi_raw.h>
|
||||
|
||||
static const struct valstr sunoem_led_type_vals[] = {
|
||||
{ 0, "OK2RM" },
|
||||
{ 1, "SERVICE" },
|
||||
{ 2, "ACT" },
|
||||
{ 3, "LOCATE" },
|
||||
{ 0, NULL },
|
||||
};
|
||||
|
||||
static const struct valstr sunoem_led_mode_vals[] = {
|
||||
{ 0, "OFF" },
|
||||
{ 1, "ON" },
|
||||
{ 2, "STANDBY" },
|
||||
{ 3, "SLOW" },
|
||||
{ 4, "FAST" },
|
||||
{ 0xFF, NULL },
|
||||
};
|
||||
static const struct valstr sunoem_led_mode_optvals[] = {
|
||||
{ 0, "STEADY_OFF" },
|
||||
{ 1, "STEADY_ON" },
|
||||
{ 2, "STANDBY_BLINK" },
|
||||
{ 3, "SLOW_BLINK" },
|
||||
{ 4, "FAST_BLINK" },
|
||||
{ 0xFF, NULL },
|
||||
};
|
||||
|
||||
static void
|
||||
ipmi_sunoem_usage(void)
|
||||
{
|
||||
lprintf(LOG_NOTICE, "usage: sunoem <command> [option...]");
|
||||
lprintf(LOG_NOTICE, "");
|
||||
lprintf(LOG_NOTICE, " fan speed <0-100>");
|
||||
lprintf(LOG_NOTICE, " Set system fan speed (PWM duty cycle)");
|
||||
lprintf(LOG_NOTICE, "");
|
||||
lprintf(LOG_NOTICE, " sshkey set <userid> <id_rsa.pub>");
|
||||
lprintf(LOG_NOTICE, " Set ssh key for a userid into authorized_keys,");
|
||||
lprintf(LOG_NOTICE, " view users with 'user list' command.");
|
||||
lprintf(LOG_NOTICE, "");
|
||||
lprintf(LOG_NOTICE, " sshkey del <userid>");
|
||||
lprintf(LOG_NOTICE, " Delete ssh key for userid from authorized_keys,");
|
||||
lprintf(LOG_NOTICE, " view users with 'user list' command.");
|
||||
lprintf(LOG_NOTICE, "");
|
||||
lprintf(LOG_NOTICE, " led get <sensorid> [ledtype]");
|
||||
lprintf(LOG_NOTICE, " Read status of LED found in Generic Device Locator.");
|
||||
lprintf(LOG_NOTICE, "");
|
||||
lprintf(LOG_NOTICE, " led set <sensorid> <ledmode> [ledtype]");
|
||||
lprintf(LOG_NOTICE, " Set mode of LED found in Generic Device Locator.");
|
||||
lprintf(LOG_NOTICE, "");
|
||||
lprintf(LOG_NOTICE, " Use 'sdr list generic' command to get list of Generic");
|
||||
lprintf(LOG_NOTICE, " Devices that are controllable LEDs.");
|
||||
lprintf(LOG_NOTICE, "");
|
||||
lprintf(LOG_NOTICE, " Required SIS LED Mode:");
|
||||
lprintf(LOG_NOTICE, " OFF Off");
|
||||
lprintf(LOG_NOTICE, " ON Steady On");
|
||||
lprintf(LOG_NOTICE, " STANDBY 100ms on 2900ms off blink rate");
|
||||
lprintf(LOG_NOTICE, " SLOW 1HZ blink rate");
|
||||
lprintf(LOG_NOTICE, " FAST 4HZ blink rate");
|
||||
lprintf(LOG_NOTICE, "");
|
||||
lprintf(LOG_NOTICE, " Optional SIS LED Type:");
|
||||
lprintf(LOG_NOTICE, " OK2RM OK to Remove");
|
||||
lprintf(LOG_NOTICE, " SERVICE Service Required");
|
||||
lprintf(LOG_NOTICE, " ACT Activity");
|
||||
lprintf(LOG_NOTICE, " LOCATE Locate");
|
||||
lprintf(LOG_NOTICE, "");
|
||||
}
|
||||
|
||||
/*
|
||||
* IPMI Request Data: 1 byte
|
||||
*
|
||||
* [byte 0] FanSpeed Fan speed as percentage
|
||||
*/
|
||||
static int
|
||||
ipmi_sunoem_fan_speed(struct ipmi_intf * intf, uint8_t speed)
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
|
||||
/*
|
||||
* sunoem fan speed <percent>
|
||||
*/
|
||||
|
||||
if (speed > 100) {
|
||||
lprintf(LOG_NOTICE, "Invalid fan speed: %d", speed);
|
||||
return -1;
|
||||
}
|
||||
|
||||
req.msg.netfn = IPMI_NETFN_SUNOEM;
|
||||
req.msg.cmd = IPMI_SUNOEM_SET_FAN_SPEED;
|
||||
req.msg.data = &speed;
|
||||
req.msg.data_len = 1;
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (rsp == NULL) {
|
||||
lprintf(LOG_ERR, "Sun OEM Set Fan Speed command failed");
|
||||
return -1;
|
||||
}
|
||||
else if (rsp->ccode > 0) {
|
||||
lprintf(LOG_ERR, "Sun OEM Set Fan Speed command failed: %s",
|
||||
val2str(rsp->ccode, completion_code_vals));
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("Set Fan speed to %d%%\n", speed);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
__sdr_list_empty(struct sdr_record_list * head)
|
||||
{
|
||||
struct sdr_record_list * e, * f;
|
||||
for (e = head; e != NULL; e = f) {
|
||||
f = e->next;
|
||||
free(e);
|
||||
}
|
||||
head = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
led_print(const char * name, uint8_t state)
|
||||
{
|
||||
if (csv_output)
|
||||
printf("%s,%s\n", name, val2str(state, sunoem_led_mode_vals));
|
||||
else
|
||||
printf("%-16s | %s\n", name, val2str(state, sunoem_led_mode_vals));
|
||||
}
|
||||
|
||||
struct ipmi_rs *
|
||||
sunoem_led_get(struct ipmi_intf * intf,
|
||||
struct sdr_record_generic_locator * dev,
|
||||
int ledtype)
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
uint8_t rqdata[5];
|
||||
|
||||
if (dev == NULL)
|
||||
return NULL;
|
||||
|
||||
rqdata[0] = dev->dev_slave_addr;
|
||||
rqdata[1] = ledtype;
|
||||
rqdata[2] = dev->dev_access_addr;
|
||||
rqdata[3] = dev->oem;
|
||||
rqdata[4] = 0;
|
||||
|
||||
req.msg.netfn = IPMI_NETFN_SUNOEM;
|
||||
req.msg.cmd = IPMI_SUNOEM_LED_GET;
|
||||
req.msg.data = rqdata;
|
||||
req.msg.data_len = 5;
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (rsp == NULL) {
|
||||
lprintf(LOG_ERR, "Sun OEM Get LED command failed");
|
||||
return NULL;
|
||||
}
|
||||
else if (rsp->ccode > 0) {
|
||||
lprintf(LOG_ERR, "Sun OEM Get LED command failed: %s",
|
||||
val2str(rsp->ccode, completion_code_vals));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return rsp;
|
||||
}
|
||||
|
||||
struct ipmi_rs *
|
||||
sunoem_led_set(struct ipmi_intf * intf,
|
||||
struct sdr_record_generic_locator * dev,
|
||||
int ledtype, int ledmode)
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
uint8_t rqdata[7];
|
||||
|
||||
if (dev == NULL)
|
||||
return NULL;
|
||||
|
||||
rqdata[0] = dev->dev_slave_addr;
|
||||
rqdata[1] = ledtype;
|
||||
rqdata[2] = dev->dev_access_addr;
|
||||
rqdata[3] = dev->oem;
|
||||
rqdata[4] = ledmode;
|
||||
rqdata[5] = 0;
|
||||
rqdata[6] = 0;
|
||||
|
||||
req.msg.netfn = IPMI_NETFN_SUNOEM;
|
||||
req.msg.cmd = IPMI_SUNOEM_LED_SET;
|
||||
req.msg.data = rqdata;
|
||||
req.msg.data_len = 7;
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (rsp == NULL) {
|
||||
lprintf(LOG_ERR, "Sun OEM Set LED command failed");
|
||||
return NULL;
|
||||
}
|
||||
else if (rsp->ccode > 0) {
|
||||
lprintf(LOG_ERR, "Sun OEM Set LED command failed: %s",
|
||||
val2str(rsp->ccode, completion_code_vals));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return rsp;
|
||||
}
|
||||
|
||||
static void
|
||||
sunoem_led_get_byentity(struct ipmi_intf * intf, uint8_t entity_id,
|
||||
uint8_t entity_inst, int ledtype)
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
struct sdr_record_list *elist, *e;
|
||||
struct entity_id entity;
|
||||
|
||||
if (entity_id == 0)
|
||||
return;
|
||||
|
||||
/* lookup sdrs with this entity */
|
||||
memset(&entity, 0, sizeof(struct entity_id));
|
||||
entity.id = entity_id;
|
||||
entity.instance = entity_inst;
|
||||
|
||||
elist = ipmi_sdr_find_sdr_byentity(intf, &entity);
|
||||
|
||||
/* for each generic sensor set its led state */
|
||||
for (e = elist; e != NULL; e = e->next) {
|
||||
if (e->type != SDR_RECORD_TYPE_GENERIC_DEVICE_LOCATOR)
|
||||
continue;
|
||||
rsp = sunoem_led_get(intf, e->record.genloc, ledtype);
|
||||
if (rsp && rsp->data_len == 1) {
|
||||
led_print((const char *)e->record.genloc->id_string, rsp->data[0]);
|
||||
}
|
||||
}
|
||||
|
||||
__sdr_list_empty(elist);
|
||||
}
|
||||
|
||||
static void
|
||||
sunoem_led_set_byentity(struct ipmi_intf * intf, uint8_t entity_id,
|
||||
uint8_t entity_inst, int ledtype, int ledmode)
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
struct sdr_record_list *elist, *e;
|
||||
struct entity_id entity;
|
||||
|
||||
if (entity_id == 0)
|
||||
return;
|
||||
|
||||
/* lookup sdrs with this entity */
|
||||
memset(&entity, 0, sizeof(struct entity_id));
|
||||
entity.id = entity_id;
|
||||
entity.instance = entity_inst;
|
||||
|
||||
elist = ipmi_sdr_find_sdr_byentity(intf, &entity);
|
||||
|
||||
/* for each generic sensor set its led state */
|
||||
for (e = elist; e != NULL; e = e->next) {
|
||||
if (e->type != SDR_RECORD_TYPE_GENERIC_DEVICE_LOCATOR)
|
||||
continue;
|
||||
rsp = sunoem_led_set(intf, e->record.genloc, ledtype, ledmode);
|
||||
if (rsp && rsp->data_len == 0) {
|
||||
led_print((const char *)e->record.genloc->id_string, ledmode);
|
||||
}
|
||||
}
|
||||
|
||||
__sdr_list_empty(elist);
|
||||
}
|
||||
|
||||
/*
|
||||
* IPMI Request Data: 5 bytes
|
||||
*
|
||||
* [byte 0] devAddr Value from the "Device Slave Address" field in
|
||||
* LED's Generic Device Locator record in the SDR
|
||||
* [byte 1] led LED Type: OK2RM, ACT, LOCATE, SERVICE
|
||||
* [byte 2] ctrlrAddr Controller address; value from the "Device
|
||||
* Access Address" field, 0x20 if the LED is local
|
||||
* [byte 3] hwInfo The OEM field from the SDR record
|
||||
* [byte 4] force 1 = directly access the device
|
||||
* 0 = go thru its controller
|
||||
* Ignored if LED is local
|
||||
*/
|
||||
static int
|
||||
ipmi_sunoem_led_get(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
struct sdr_record_list *sdr;
|
||||
struct sdr_record_list *alist, *a;
|
||||
struct sdr_record_entity_assoc *assoc;
|
||||
int ledtype = 0;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* sunoem led get <id> [type]
|
||||
*/
|
||||
|
||||
if (argc < 1 || strncmp(argv[0], "help", 4) == 0) {
|
||||
lprintf(LOG_NOTICE, "usage: sunoem led get <id> [type]");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (argc > 1) {
|
||||
ledtype = str2val(argv[1], sunoem_led_type_vals);
|
||||
}
|
||||
|
||||
if (strncasecmp(argv[0], "all", 3) == 0) {
|
||||
/* do all generic sensors */
|
||||
alist = ipmi_sdr_find_sdr_bytype(intf, SDR_RECORD_TYPE_GENERIC_DEVICE_LOCATOR);
|
||||
for (a = alist; a != NULL; a = a->next) {
|
||||
if (a->type != SDR_RECORD_TYPE_GENERIC_DEVICE_LOCATOR)
|
||||
continue;
|
||||
if (a->record.genloc->entity.logical)
|
||||
continue;
|
||||
rsp = sunoem_led_get(intf, a->record.genloc, ledtype);
|
||||
if (rsp && rsp->data_len == 1) {
|
||||
led_print((const char *)a->record.genloc->id_string, rsp->data[0]);
|
||||
}
|
||||
}
|
||||
__sdr_list_empty(alist);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* look up generic device locator record in SDR */
|
||||
sdr = ipmi_sdr_find_sdr_byid(intf, argv[0]);
|
||||
|
||||
if (sdr == NULL) {
|
||||
lprintf(LOG_ERR, "No Sensor Data Record found for %s", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (sdr->type != SDR_RECORD_TYPE_GENERIC_DEVICE_LOCATOR) {
|
||||
lprintf(LOG_ERR, "Invalid SDR type %d", sdr->type);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!sdr->record.genloc->entity.logical) {
|
||||
/*
|
||||
* handle physical entity
|
||||
*/
|
||||
rsp = sunoem_led_get(intf, sdr->record.genloc, ledtype);
|
||||
if (rsp && rsp->data_len == 1) {
|
||||
led_print((const char *)sdr->record.genloc->id_string, rsp->data[0]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* handle logical entity for LED grouping
|
||||
*/
|
||||
|
||||
lprintf(LOG_INFO, "LED %s is logical device", argv[0]);
|
||||
|
||||
/* get entity assoc records */
|
||||
alist = ipmi_sdr_find_sdr_bytype(intf, SDR_RECORD_TYPE_ENTITY_ASSOC);
|
||||
for (a = alist; a != NULL; a = a->next) {
|
||||
if (a->type != SDR_RECORD_TYPE_ENTITY_ASSOC)
|
||||
continue;
|
||||
assoc = a->record.entassoc;
|
||||
if (assoc == NULL)
|
||||
continue;
|
||||
|
||||
/* check that the entity id/instance matches our generic record */
|
||||
if (assoc->entity.id != sdr->record.genloc->entity.id ||
|
||||
assoc->entity.instance != sdr->record.genloc->entity.instance)
|
||||
continue;
|
||||
|
||||
if (assoc->flags.isrange) {
|
||||
/*
|
||||
* handle ranged entity associations
|
||||
*
|
||||
* the test for non-zero entity id is handled in
|
||||
* sunoem_led_get_byentity()
|
||||
*/
|
||||
|
||||
/* first range set - id 1 and 2 must be equal */
|
||||
if (assoc->entity_id_1 == assoc->entity_id_2)
|
||||
for (i = assoc->entity_inst_1; i <= assoc->entity_inst_2; i++)
|
||||
sunoem_led_get_byentity(intf, assoc->entity_id_1, i, ledtype);
|
||||
|
||||
/* second range set - id 3 and 4 must be equal */
|
||||
if (assoc->entity_id_3 == assoc->entity_id_4)
|
||||
for (i = assoc->entity_inst_3; i <= assoc->entity_inst_4; i++)
|
||||
sunoem_led_get_byentity(intf, assoc->entity_id_3, i, ledtype);
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* handle entity list
|
||||
*/
|
||||
sunoem_led_get_byentity(intf, assoc->entity_id_1,
|
||||
assoc->entity_inst_1, ledtype);
|
||||
sunoem_led_get_byentity(intf, assoc->entity_id_2,
|
||||
assoc->entity_inst_2, ledtype);
|
||||
sunoem_led_get_byentity(intf, assoc->entity_id_3,
|
||||
assoc->entity_inst_3, ledtype);
|
||||
sunoem_led_get_byentity(intf, assoc->entity_id_4,
|
||||
assoc->entity_inst_4, ledtype);
|
||||
}
|
||||
}
|
||||
|
||||
__sdr_list_empty(alist);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* IPMI Request Data: 7 bytes
|
||||
*
|
||||
* [byte 0] devAddr Value from the "Device Slave Address" field in
|
||||
* LED's Generic Device Locator record in the SDR
|
||||
* [byte 1] led LED Type: OK2RM, ACT, LOCATE, SERVICE
|
||||
* [byte 2] ctrlrAddr Controller address; value from the "Device
|
||||
* Access Address" field, 0x20 if the LED is local
|
||||
* [byte 3] hwInfo The OEM field from the SDR record
|
||||
* [byte 4] mode LED Mode: OFF, ON, STANDBY, SLOW, FAST
|
||||
* [byte 5] force TRUE - directly access the device
|
||||
* FALSE - go thru its controller
|
||||
* Ignored if LED is local
|
||||
* [byte 6] role Used by BMC for authorization purposes
|
||||
*
|
||||
*
|
||||
* IPMI Response Data: 1 byte
|
||||
*
|
||||
* [byte 0] mode LED Mode: OFF, ON, STANDBY, SLOW, FAST
|
||||
*/
|
||||
|
||||
static int
|
||||
ipmi_sunoem_led_set(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
struct sdr_record_list *sdr;
|
||||
struct sdr_record_list *alist, *a;
|
||||
struct sdr_record_entity_assoc *assoc;
|
||||
int ledmode;
|
||||
int ledtype = 0;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* sunoem led set <id> <mode> [type]
|
||||
*/
|
||||
|
||||
if (argc < 2 || strncmp(argv[0], "help", 4) == 0) {
|
||||
ipmi_sunoem_usage();
|
||||
return 0;
|
||||
}
|
||||
|
||||
ledmode = str2val(argv[1], sunoem_led_mode_vals);
|
||||
if (ledmode == 0xFF) {
|
||||
ledmode = str2val(argv[1], sunoem_led_mode_optvals);
|
||||
if (ledmode == 0xFF) {
|
||||
lprintf(LOG_NOTICE, "Invalid LED Mode: %s", argv[1]);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (argc > 3) {
|
||||
ledtype = str2val(argv[2], sunoem_led_type_vals);
|
||||
}
|
||||
|
||||
if (strncasecmp(argv[0], "all", 3) == 0) {
|
||||
/* do all generic sensors */
|
||||
alist = ipmi_sdr_find_sdr_bytype(intf, SDR_RECORD_TYPE_GENERIC_DEVICE_LOCATOR);
|
||||
for (a = alist; a != NULL; a = a->next) {
|
||||
if (a->type != SDR_RECORD_TYPE_GENERIC_DEVICE_LOCATOR)
|
||||
continue;
|
||||
if (a->record.genloc->entity.logical)
|
||||
continue;
|
||||
rsp = sunoem_led_set(intf, a->record.genloc, ledtype, ledmode);
|
||||
if (rsp && rsp->ccode == 0) {
|
||||
led_print((const char *)a->record.genloc->id_string, ledmode);
|
||||
}
|
||||
}
|
||||
__sdr_list_empty(alist);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* look up generic device locator records in SDR */
|
||||
sdr = ipmi_sdr_find_sdr_byid(intf, argv[0]);
|
||||
|
||||
if (sdr == NULL) {
|
||||
lprintf(LOG_ERR, "No Sensor Data Record found for %s",
|
||||
argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (sdr->type != SDR_RECORD_TYPE_GENERIC_DEVICE_LOCATOR) {
|
||||
lprintf(LOG_ERR, "Invalid SDR type %d", sdr->type);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!sdr->record.genloc->entity.logical) {
|
||||
/*
|
||||
* handle physical entity
|
||||
*/
|
||||
rsp = sunoem_led_set(intf, sdr->record.genloc, ledtype, ledmode);
|
||||
if (rsp && rsp->ccode == 0) {
|
||||
led_print(argv[0], ledmode);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* handle logical entity for LED grouping
|
||||
*/
|
||||
|
||||
lprintf(LOG_INFO, "LED %s is logical device", argv[0]);
|
||||
|
||||
/* get entity assoc records */
|
||||
alist = ipmi_sdr_find_sdr_bytype(intf, SDR_RECORD_TYPE_ENTITY_ASSOC);
|
||||
for (a = alist; a != NULL; a = a->next) {
|
||||
if (a->type != SDR_RECORD_TYPE_ENTITY_ASSOC)
|
||||
continue;
|
||||
assoc = a->record.entassoc;
|
||||
if (assoc == NULL)
|
||||
continue;
|
||||
|
||||
/* check that the entity id/instance matches our generic record */
|
||||
if (assoc->entity.id != sdr->record.genloc->entity.id ||
|
||||
assoc->entity.instance != sdr->record.genloc->entity.instance)
|
||||
continue;
|
||||
|
||||
if (assoc->flags.isrange) {
|
||||
/*
|
||||
* handle ranged entity associations
|
||||
*
|
||||
* the test for non-zero entity id is handled in
|
||||
* sunoem_led_get_byentity()
|
||||
*/
|
||||
|
||||
/* first range set - id 1 and 2 must be equal */
|
||||
if (assoc->entity_id_1 == assoc->entity_id_2)
|
||||
for (i = assoc->entity_inst_1; i <= assoc->entity_inst_2; i++)
|
||||
sunoem_led_set_byentity(intf, assoc->entity_id_1, i, ledtype, ledmode);
|
||||
|
||||
/* second range set - id 3 and 4 must be equal */
|
||||
if (assoc->entity_id_3 == assoc->entity_id_4)
|
||||
for (i = assoc->entity_inst_3; i <= assoc->entity_inst_4; i++)
|
||||
sunoem_led_set_byentity(intf, assoc->entity_id_3, i, ledtype, ledmode);
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* handle entity list
|
||||
*/
|
||||
sunoem_led_set_byentity(intf, assoc->entity_id_1,
|
||||
assoc->entity_inst_1, ledtype, ledmode);
|
||||
sunoem_led_set_byentity(intf, assoc->entity_id_2,
|
||||
assoc->entity_inst_2, ledtype, ledmode);
|
||||
sunoem_led_set_byentity(intf, assoc->entity_id_3,
|
||||
assoc->entity_inst_3, ledtype, ledmode);
|
||||
sunoem_led_set_byentity(intf, assoc->entity_id_4,
|
||||
assoc->entity_inst_4, ledtype, ledmode);
|
||||
}
|
||||
}
|
||||
|
||||
__sdr_list_empty(alist);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ipmi_sunoem_sshkey_del(struct ipmi_intf * intf, uint8_t uid)
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
|
||||
memset(&req, 0, sizeof(struct ipmi_rq));
|
||||
req.msg.netfn = IPMI_NETFN_SUNOEM;
|
||||
req.msg.cmd = IPMI_SUNOEM_DEL_SSH_KEY;
|
||||
req.msg.data = &uid;
|
||||
req.msg.data_len = 1;
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (rsp == NULL) {
|
||||
lprintf(LOG_ERR, "Unable to delete ssh key for UID %d", uid);
|
||||
return -1;
|
||||
}
|
||||
else if (rsp->ccode > 0) {
|
||||
lprintf(LOG_ERR, "Unable to delete ssh key for UID %d: %s", uid,
|
||||
val2str(rsp->ccode, completion_code_vals));
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("Deleted SSH key for user id %d\n", uid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define SSHKEY_BLOCK_SIZE 64
|
||||
static int
|
||||
ipmi_sunoem_sshkey_set(struct ipmi_intf * intf, uint8_t uid, char * ifile)
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
FILE * fp;
|
||||
int count;
|
||||
uint16_t i_size, r, size;
|
||||
uint8_t wbuf[SSHKEY_BLOCK_SIZE + 3];
|
||||
|
||||
if (ifile == NULL) {
|
||||
lprintf(LOG_ERR, "Invalid or misisng input filename");
|
||||
return -1;
|
||||
}
|
||||
|
||||
fp = ipmi_open_file_read(ifile);
|
||||
if (fp == NULL) {
|
||||
lprintf(LOG_ERR, "Unable to open file %s for reading", ifile);
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("Setting SSH key for user id %d...", uid);
|
||||
|
||||
memset(&req, 0, sizeof(struct ipmi_rq));
|
||||
req.msg.netfn = IPMI_NETFN_SUNOEM;
|
||||
req.msg.cmd = IPMI_SUNOEM_SET_SSH_KEY;
|
||||
req.msg.data = wbuf;
|
||||
|
||||
fseek(fp, 0, SEEK_END);
|
||||
size = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
|
||||
for (r = 0; r < size; r += i_size) {
|
||||
i_size = size - r;
|
||||
if (i_size > SSHKEY_BLOCK_SIZE)
|
||||
i_size = SSHKEY_BLOCK_SIZE;
|
||||
|
||||
memset(wbuf, 0, SSHKEY_BLOCK_SIZE);
|
||||
fseek(fp, r, SEEK_SET);
|
||||
count = fread(wbuf+3, 1, i_size, fp);
|
||||
if (count != i_size) {
|
||||
lprintf(LOG_ERR, "Unable to read %d bytes from file %s", i_size, ifile);
|
||||
fclose(fp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf(".");
|
||||
fflush(stdout);
|
||||
|
||||
wbuf[0] = uid;
|
||||
if ((r + SSHKEY_BLOCK_SIZE) >= size)
|
||||
wbuf[1] = 0xff;
|
||||
else
|
||||
wbuf[1] = (uint8_t)(r / SSHKEY_BLOCK_SIZE);
|
||||
wbuf[2] = i_size;
|
||||
req.msg.data_len = i_size + 3;
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (rsp == NULL) {
|
||||
lprintf(LOG_ERR, "Unable to set ssh key for UID %d", uid);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
printf("done\n");
|
||||
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ipmi_sunoem_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (argc == 0 || strncmp(argv[0], "help", 4) == 0) {
|
||||
ipmi_sunoem_usage();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strncmp(argv[0], "fan", 3) == 0) {
|
||||
uint8_t pct;
|
||||
if (argc < 2) {
|
||||
ipmi_sunoem_usage();
|
||||
return -1;
|
||||
}
|
||||
else if (strncmp(argv[1], "speed", 5) == 0) {
|
||||
if (argc < 3) {
|
||||
ipmi_sunoem_usage();
|
||||
return -1;
|
||||
}
|
||||
pct = (uint8_t)strtol(argv[2], NULL, 0);
|
||||
rc = ipmi_sunoem_fan_speed(intf, pct);
|
||||
}
|
||||
else {
|
||||
ipmi_sunoem_usage();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (strncmp(argv[0], "led", 3) == 0) {
|
||||
if (argc < 2) {
|
||||
ipmi_sunoem_usage();
|
||||
return -1;
|
||||
}
|
||||
if (strncmp(argv[1], "get", 3) == 0) {
|
||||
if (argc < 3) {
|
||||
char * arg[] = { "all" };
|
||||
rc = ipmi_sunoem_led_get(intf, 1, arg);
|
||||
} else {
|
||||
rc = ipmi_sunoem_led_get(intf, argc-2, &(argv[2]));
|
||||
}
|
||||
}
|
||||
else if (strncmp(argv[1], "set", 3) == 0) {
|
||||
if (argc < 4) {
|
||||
ipmi_sunoem_usage();
|
||||
return -1;
|
||||
}
|
||||
rc = ipmi_sunoem_led_set(intf, argc-2, &(argv[2]));
|
||||
}
|
||||
else {
|
||||
ipmi_sunoem_usage();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (strncmp(argv[0], "sshkey", 6) == 0) {
|
||||
if (argc < 2) {
|
||||
ipmi_sunoem_usage();
|
||||
return -1;
|
||||
}
|
||||
else if (strncmp(argv[1], "del", 3) == 0) {
|
||||
uint8_t uid;
|
||||
if (argc < 3) {
|
||||
ipmi_sunoem_usage();
|
||||
return -1;
|
||||
}
|
||||
uid = (uint8_t)strtoul(argv[2], NULL, 0);
|
||||
rc = ipmi_sunoem_sshkey_del(intf, uid);
|
||||
}
|
||||
else if (strncmp(argv[1], "set", 3) == 0) {
|
||||
uint8_t uid;
|
||||
if (argc < 4) {
|
||||
ipmi_sunoem_usage();
|
||||
return -1;
|
||||
}
|
||||
uid = (uint8_t)strtoul(argv[2], NULL, 0);
|
||||
rc = ipmi_sunoem_sshkey_set(intf, uid, argv[3]);
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
596
ipmitool/lib/ipmi_tsol.c
Normal file
596
ipmitool/lib/ipmi_tsol.c
Normal file
@ -0,0 +1,596 @@
|
||||
/*
|
||||
* Copyright (c) 2005 Tyan Computer Corp. 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 <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/poll.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <sys/select.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#ifdef __linux__
|
||||
# include <linux/termios.h>
|
||||
#else
|
||||
# include <sys/termios.h>
|
||||
#endif
|
||||
|
||||
#include <ipmitool/log.h>
|
||||
#include <ipmitool/helper.h>
|
||||
#include <ipmitool/ipmi.h>
|
||||
#include <ipmitool/ipmi_intf.h>
|
||||
#include <ipmitool/ipmi_tsol.h>
|
||||
#include <ipmitool/ipmi_strings.h>
|
||||
#include <ipmitool/bswap.h>
|
||||
|
||||
#include <config.h>
|
||||
|
||||
static struct timeval _start_keepalive;
|
||||
static struct termios _saved_tio;
|
||||
static struct winsize _saved_winsize;
|
||||
static int _in_raw_mode = 0;
|
||||
static int _altterm = 0;
|
||||
|
||||
static int
|
||||
ipmi_tsol_command(struct ipmi_intf * intf, char *recvip, int port, unsigned char cmd)
|
||||
{
|
||||
struct ipmi_rs *rsp;
|
||||
struct ipmi_rq req;
|
||||
unsigned char data[6];
|
||||
unsigned ip1, ip2, ip3, ip4;
|
||||
uint16_t portin;
|
||||
|
||||
#if WORDS_BIGENDIAN
|
||||
portin = BSWAP_16(port);
|
||||
#else
|
||||
portin = port;
|
||||
#endif
|
||||
|
||||
if (sscanf(recvip, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4) != 4) {
|
||||
lprintf(LOG_ERR, "Invalid IP address: %s", recvip);
|
||||
return -1;
|
||||
}
|
||||
|
||||
req.msg.netfn = IPMI_NETFN_TSOL;
|
||||
req.msg.cmd = cmd;
|
||||
req.msg.data_len = 6;
|
||||
req.msg.data = data;
|
||||
|
||||
memset(data, 0, sizeof(data));
|
||||
data[0] = ip1;
|
||||
data[1] = ip2;
|
||||
data[2] = ip3;
|
||||
data[3] = ip4;
|
||||
data[4] = (portin & 0xff00) >> 8;
|
||||
data[5] = (portin & 0xff);
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (rsp == NULL) {
|
||||
lprintf(LOG_ERR, "Unable to perform TSOL command");
|
||||
return -1;
|
||||
}
|
||||
if (rsp->ccode > 0) {
|
||||
lprintf(LOG_ERR, "Unable to perform TSOL command: %s",
|
||||
val2str(rsp->ccode, completion_code_vals));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ipmi_tsol_start(struct ipmi_intf * intf, char *recvip, int port)
|
||||
{
|
||||
return ipmi_tsol_command(intf, recvip, port, IPMI_TSOL_CMD_START);
|
||||
}
|
||||
|
||||
static int
|
||||
ipmi_tsol_stop(struct ipmi_intf * intf, char *recvip, int port)
|
||||
{
|
||||
return ipmi_tsol_command(intf, recvip, port, IPMI_TSOL_CMD_STOP);
|
||||
}
|
||||
|
||||
static int
|
||||
ipmi_tsol_send_keystroke(struct ipmi_intf * intf, char *buff, int length)
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
unsigned char data[16];
|
||||
static unsigned char keyseq = 0;
|
||||
|
||||
req.msg.netfn = IPMI_NETFN_TSOL;
|
||||
req.msg.cmd = IPMI_TSOL_CMD_SENDKEY;
|
||||
req.msg.data_len = length + 2;
|
||||
req.msg.data = data;
|
||||
|
||||
memset(data, 0, sizeof(data));
|
||||
data[0] = length + 1;
|
||||
memcpy(data + 1, buff, length);
|
||||
data[length + 1] = keyseq++;
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (rsp == NULL) {
|
||||
lprintf(LOG_ERR, "Unable to send keystroke");
|
||||
return -1;
|
||||
}
|
||||
if (rsp->ccode > 0) {
|
||||
lprintf(LOG_ERR, "Unable to send keystroke: %s",
|
||||
val2str(rsp->ccode, completion_code_vals));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
static int
|
||||
tsol_keepalive(struct ipmi_intf * intf)
|
||||
{
|
||||
struct timeval end;
|
||||
|
||||
gettimeofday(&end, 0);
|
||||
|
||||
if (end.tv_sec - _start_keepalive.tv_sec <= 30)
|
||||
return 0;
|
||||
|
||||
intf->keepalive(intf);
|
||||
|
||||
gettimeofday(&_start_keepalive, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
print_escape_seq(struct ipmi_intf *intf)
|
||||
{
|
||||
lprintf(LOG_NOTICE,
|
||||
" %c. - terminate connection\r\n"
|
||||
" %c^Z - suspend ipmitool\r\n"
|
||||
" %c^X - suspend ipmitool, but don't restore tty on restart\r\n"
|
||||
" %c? - this message\r\n"
|
||||
" %c%c - send the escape character by typing it twice\r\n"
|
||||
" (Note that escapes are only recognized immediately after newline.)\r",
|
||||
intf->session->sol_escape_char,
|
||||
intf->session->sol_escape_char,
|
||||
intf->session->sol_escape_char,
|
||||
intf->session->sol_escape_char,
|
||||
intf->session->sol_escape_char,
|
||||
intf->session->sol_escape_char);
|
||||
}
|
||||
|
||||
static int
|
||||
leave_raw_mode(void)
|
||||
{
|
||||
if (!_in_raw_mode)
|
||||
return -1;
|
||||
else if (tcsetattr(fileno(stdin), TCSADRAIN, &_saved_tio) == -1)
|
||||
lperror(LOG_ERR, "tcsetattr(stdin)");
|
||||
else if (tcsetattr(fileno(stdout), TCSADRAIN, &_saved_tio) == -1)
|
||||
lperror(LOG_ERR, "tcsetattr(stdout)");
|
||||
else
|
||||
_in_raw_mode = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
enter_raw_mode(void)
|
||||
{
|
||||
struct termios tio;
|
||||
|
||||
if (tcgetattr(fileno(stdout), &_saved_tio) < 0) {
|
||||
lperror(LOG_ERR, "tcgetattr failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
tio = _saved_tio;
|
||||
|
||||
if (_altterm) {
|
||||
tio.c_iflag &= (ISTRIP | IGNBRK );
|
||||
tio.c_cflag &= ~(CSIZE | PARENB | IXON | IXOFF | IXANY);
|
||||
tio.c_cflag |= (CS8 |CREAD) | (IXON|IXOFF|IXANY);
|
||||
tio.c_lflag &= 0;
|
||||
tio.c_cc[VMIN] = 1;
|
||||
tio.c_cc[VTIME] = 0;
|
||||
} else {
|
||||
tio.c_iflag |= IGNPAR;
|
||||
tio.c_iflag &= ~(ISTRIP | INLCR | IGNCR | ICRNL | IXON | IXANY | IXOFF);
|
||||
tio.c_lflag &= ~(ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHONL | IEXTEN);
|
||||
tio.c_oflag &= ~OPOST;
|
||||
tio.c_cc[VMIN] = 1;
|
||||
tio.c_cc[VTIME] = 0;
|
||||
}
|
||||
|
||||
if (tcsetattr(fileno(stdin), TCSADRAIN, &tio) < 0)
|
||||
lperror(LOG_ERR, "tcsetattr(stdin)");
|
||||
else if (tcsetattr(fileno(stdout), TCSADRAIN, &tio) < 0)
|
||||
lperror(LOG_ERR, "tcsetattr(stdout)");
|
||||
else
|
||||
_in_raw_mode = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
suspend_self(int restore_tty)
|
||||
{
|
||||
leave_raw_mode();
|
||||
|
||||
kill(getpid(), SIGTSTP);
|
||||
|
||||
if (restore_tty)
|
||||
enter_raw_mode();
|
||||
}
|
||||
|
||||
static int
|
||||
do_inbuf_actions(struct ipmi_intf *intf, char *in_buff, int len)
|
||||
{
|
||||
static int in_esc = 0;
|
||||
static int last_was_cr = 1;
|
||||
int i;
|
||||
|
||||
for(i = 0; i < len ;) {
|
||||
if (!in_esc) {
|
||||
if (last_was_cr &&
|
||||
(in_buff[i] == intf->session->sol_escape_char)) {
|
||||
in_esc = 1;
|
||||
memmove(in_buff, in_buff + 1, len - i - 1);
|
||||
len--;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (in_esc) {
|
||||
if (in_buff[i] == intf->session->sol_escape_char) {
|
||||
in_esc = 0;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (in_buff[i]) {
|
||||
case '.':
|
||||
printf("%c. [terminated ipmitool]\r\n",
|
||||
intf->session->sol_escape_char);
|
||||
return -1;
|
||||
|
||||
case 'Z' - 64:
|
||||
printf("%c^Z [suspend ipmitool]\r\n",
|
||||
intf->session->sol_escape_char);
|
||||
suspend_self(1); /* Restore tty back to raw */
|
||||
break;
|
||||
|
||||
case 'X' - 64:
|
||||
printf("%c^X [suspend ipmitool]\r\n",
|
||||
intf->session->sol_escape_char);
|
||||
suspend_self(0); /* Don't restore to raw mode */
|
||||
break;
|
||||
|
||||
case '?':
|
||||
printf("%c? [ipmitool help]\r\n",
|
||||
intf->session->sol_escape_char);
|
||||
print_escape_seq(intf);
|
||||
break;
|
||||
}
|
||||
|
||||
memmove(in_buff, in_buff + 1, len - i - 1);
|
||||
len--;
|
||||
in_esc = 0;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
last_was_cr = (in_buff[i] == '\r' || in_buff[i] == '\n');
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
do_terminal_cleanup(void)
|
||||
{
|
||||
if (_saved_winsize.ws_row > 0 && _saved_winsize.ws_col > 0)
|
||||
ioctl(fileno(stdout), TIOCSWINSZ, &_saved_winsize);
|
||||
|
||||
leave_raw_mode();
|
||||
|
||||
if (errno)
|
||||
lprintf(LOG_ERR, "Exiting due to error %d -> %s",
|
||||
errno, strerror(errno));
|
||||
}
|
||||
|
||||
static void
|
||||
set_terminal_size(int rows, int cols)
|
||||
{
|
||||
struct winsize winsize;
|
||||
|
||||
if (rows <= 0 || cols <= 0)
|
||||
return;
|
||||
|
||||
/* save initial winsize */
|
||||
ioctl(fileno(stdout), TIOCGWINSZ, &_saved_winsize);
|
||||
|
||||
/* set new winsize */
|
||||
winsize.ws_row = rows;
|
||||
winsize.ws_col = cols;
|
||||
ioctl(fileno(stdout), TIOCSWINSZ, &winsize);
|
||||
}
|
||||
|
||||
static void
|
||||
print_tsol_usage(void)
|
||||
{
|
||||
struct winsize winsize;
|
||||
|
||||
lprintf(LOG_NOTICE, "Usage: tsol [recvip] [port=NUM] [ro|rw] [rows=NUM] [cols=NUM] [altterm]");
|
||||
lprintf(LOG_NOTICE, " recvip Receiver IP Address [default=local]");
|
||||
lprintf(LOG_NOTICE, " port=NUM Receiver UDP Port [default=%d]",
|
||||
IPMI_TSOL_DEF_PORT);
|
||||
lprintf(LOG_NOTICE, " ro|rw Set Read-Only or Read-Write [default=rw]");
|
||||
|
||||
ioctl(fileno(stdout), TIOCGWINSZ, &winsize);
|
||||
lprintf(LOG_NOTICE, " rows=NUM Set terminal rows [default=%d]",
|
||||
winsize.ws_row);
|
||||
lprintf(LOG_NOTICE, " cols=NUM Set terminal columns [default=%d]",
|
||||
winsize.ws_col);
|
||||
|
||||
lprintf(LOG_NOTICE, " altterm Alternate terminal setup [default=off]");
|
||||
}
|
||||
|
||||
int
|
||||
ipmi_tsol_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
{
|
||||
struct pollfd fds_wait[3], fds_data_wait[3], *fds;
|
||||
struct sockaddr_in sin, myaddr;
|
||||
socklen_t mylen;
|
||||
char recvip_c[] = "0.0.0.0";
|
||||
char *recvip = NULL;
|
||||
char out_buff[IPMI_BUF_SIZE * 8], in_buff[IPMI_BUF_SIZE];
|
||||
char buff[IPMI_BUF_SIZE + 4];
|
||||
int fd_socket, result, i;
|
||||
int out_buff_fill, in_buff_fill;
|
||||
int ip1, ip2, ip3, ip4;
|
||||
int read_only = 0, rows = 0, cols = 0;
|
||||
int port = IPMI_TSOL_DEF_PORT;
|
||||
|
||||
if (strlen(intf->name) == 3 && strncmp(intf->name, "lan", 3) != 0) {
|
||||
lprintf(LOG_ERR, "Error: Tyan SOL is only available over lan interface");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i<argc; i++) {
|
||||
if (sscanf(argv[i], "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4) == 4)
|
||||
recvip = strdup(argv[i]);
|
||||
else if (sscanf(argv[i], "port=%d", &ip1) == 1)
|
||||
port = ip1;
|
||||
else if (sscanf(argv[i], "rows=%d", &ip1) == 1)
|
||||
rows = ip1;
|
||||
else if (sscanf(argv[i], "cols=%d", &ip1) == 1)
|
||||
cols = ip1;
|
||||
else if (strlen(argv[i]) == 2 && strncmp(argv[i], "ro", 2) == 0)
|
||||
read_only = 1;
|
||||
else if (strlen(argv[i]) == 2 && strncmp(argv[i], "rw", 2) == 0)
|
||||
read_only = 0;
|
||||
else if (strlen(argv[i]) == 7 && strncmp(argv[i], "altterm", 7) == 0)
|
||||
_altterm = 1;
|
||||
else if (strlen(argv[i]) == 4 && strncmp(argv[i], "help", 4) == 0) {
|
||||
print_tsol_usage();
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
print_tsol_usage();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* create udp socket to receive the packet */
|
||||
memset(&sin, 0, sizeof(sin));
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_port = htons(port);
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
result = inet_aton((const char *)intf->session->hostname,
|
||||
&intf->session->addr.sin_addr);
|
||||
#else
|
||||
result = inet_pton(AF_INET, (const char *)intf->session->hostname,
|
||||
&intf->session->addr.sin_addr);
|
||||
#endif
|
||||
|
||||
if (result <= 0) {
|
||||
struct hostent *host = gethostbyname((const char *)intf->session->hostname);
|
||||
if (host == NULL ) {
|
||||
lprintf(LOG_ERR, "Address lookup for %s failed",
|
||||
intf->session->hostname);
|
||||
return -1;
|
||||
}
|
||||
intf->session->addr.sin_family = host->h_addrtype;
|
||||
memcpy(&intf->session->addr.sin_addr, host->h_addr, host->h_length);
|
||||
}
|
||||
|
||||
fd_socket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (fd_socket < 0) {
|
||||
lprintf(LOG_ERR, "Can't open port %d", port);
|
||||
return -1;
|
||||
}
|
||||
bind(fd_socket, (struct sockaddr *)&sin, sizeof(sin));
|
||||
|
||||
/*
|
||||
* retrieve local IP address if not supplied on command line
|
||||
*/
|
||||
if (recvip == NULL) {
|
||||
result = intf->open(intf); /* must connect first */
|
||||
if (result < 0)
|
||||
return -1;
|
||||
|
||||
mylen = sizeof(myaddr);
|
||||
if (getsockname(intf->fd, (struct sockaddr *)&myaddr, &mylen) < 0) {
|
||||
lperror(LOG_ERR, "getsockname failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
recvip = inet_ntoa(myaddr.sin_addr);
|
||||
if (recvip == NULL) {
|
||||
lprintf(LOG_ERR, "Unable to find local IP address");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
printf("[Starting %sSOL with receiving address %s:%d]\r\n",
|
||||
read_only ? "Read-only " : "", recvip, port);
|
||||
|
||||
set_terminal_size(rows, cols);
|
||||
enter_raw_mode();
|
||||
|
||||
/*
|
||||
* talk to smdc to start Console redirect - IP address and port as parameter
|
||||
* ipmitool -I lan -H 192.168.168.227 -U Administrator raw 0x30 0x06 0xC0 0xA8 0xA8 0x78 0x1A 0x0A
|
||||
*/
|
||||
result = ipmi_tsol_start(intf, recvip, port);
|
||||
if (result < 0) {
|
||||
lprintf(LOG_ERR, "Error starting SOL");
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("[SOL Session operational. Use %c? for help]\r\n",
|
||||
intf->session->sol_escape_char);
|
||||
|
||||
gettimeofday(&_start_keepalive, 0);
|
||||
|
||||
fds_wait[0].fd = fd_socket;
|
||||
fds_wait[0].events = POLLIN;
|
||||
fds_wait[0].revents = 0;
|
||||
fds_wait[1].fd = fileno(stdin);
|
||||
fds_wait[1].events = POLLIN;
|
||||
fds_wait[1].revents = 0;
|
||||
fds_wait[2].fd = -1;
|
||||
fds_wait[2].events = 0;
|
||||
fds_wait[2].revents = 0;
|
||||
|
||||
fds_data_wait[0].fd = fd_socket;
|
||||
fds_data_wait[0].events = POLLIN | POLLOUT;
|
||||
fds_data_wait[0].revents = 0;
|
||||
fds_data_wait[1].fd = fileno(stdin);
|
||||
fds_data_wait[1].events = POLLIN;
|
||||
fds_data_wait[1].revents = 0;
|
||||
fds_data_wait[2].fd = fileno(stdout);
|
||||
fds_data_wait[2].events = POLLOUT;
|
||||
fds_data_wait[2].revents = 0;
|
||||
|
||||
out_buff_fill = 0;
|
||||
in_buff_fill = 0;
|
||||
fds = fds_wait;
|
||||
|
||||
for (;;) {
|
||||
result = poll(fds, 3, 15*1000);
|
||||
if (result < 0)
|
||||
break;
|
||||
|
||||
/* send keepalive packet */
|
||||
tsol_keepalive(intf);
|
||||
|
||||
if ((fds[0].revents & POLLIN) && (sizeof(out_buff) > out_buff_fill)){
|
||||
socklen_t sin_len = sizeof(sin);
|
||||
result = recvfrom(fd_socket, buff, sizeof(out_buff) - out_buff_fill + 4, 0,
|
||||
(struct sockaddr *)&sin, &sin_len);
|
||||
|
||||
/* read the data from udp socket, skip some bytes in the head */
|
||||
if((result - 4) > 0 ){
|
||||
int length = result - 4;
|
||||
#if 1
|
||||
length = (unsigned char)buff[2] & 0xff;
|
||||
length *= 256;
|
||||
length += ((unsigned char)buff[3] & 0xff);
|
||||
if ((length <= 0) || (length > (result - 4)))
|
||||
length = result - 4;
|
||||
#endif
|
||||
memcpy(out_buff + out_buff_fill, buff + 4, length);
|
||||
out_buff_fill += length;
|
||||
}
|
||||
}
|
||||
if ((fds[1].revents & POLLIN) && (sizeof(in_buff) > in_buff_fill)) {
|
||||
result = read(fileno(stdin), in_buff + in_buff_fill,
|
||||
sizeof(in_buff) - in_buff_fill); // read from keyboard
|
||||
if (result > 0) {
|
||||
int bytes;
|
||||
bytes = do_inbuf_actions(intf, in_buff + in_buff_fill, result);
|
||||
if(bytes < 0) {
|
||||
result = ipmi_tsol_stop(intf, recvip, port);
|
||||
do_terminal_cleanup();
|
||||
return result;
|
||||
}
|
||||
if (read_only)
|
||||
bytes = 0;
|
||||
in_buff_fill += bytes;
|
||||
}
|
||||
}
|
||||
if ((fds[2].revents & POLLOUT) && out_buff_fill) {
|
||||
result = write(fileno(stdout), out_buff, out_buff_fill); // to screen
|
||||
if (result > 0) {
|
||||
out_buff_fill -= result;
|
||||
if (out_buff_fill) {
|
||||
memmove(out_buff, out_buff + result, out_buff_fill);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((fds[0].revents & POLLOUT) && in_buff_fill) {
|
||||
/*
|
||||
* translate key and send that to SMDC using IPMI
|
||||
* ipmitool -I lan -H 192.168.168.227 -U Administrator raw 0x30 0x03 0x04 0x1B 0x5B 0x43
|
||||
*/
|
||||
result = ipmi_tsol_send_keystroke(intf, in_buff, __min(in_buff_fill,14));
|
||||
if (result > 0) {
|
||||
gettimeofday(&_start_keepalive, 0);
|
||||
in_buff_fill -= result;
|
||||
if (in_buff_fill) {
|
||||
memmove(in_buff, in_buff + result, in_buff_fill);
|
||||
}
|
||||
}
|
||||
}
|
||||
fds = (in_buff_fill || out_buff_fill )?
|
||||
fds_data_wait : fds_wait;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -142,6 +142,8 @@ ipmi_get_user_name(
|
||||
struct ipmi_rq req;
|
||||
uint8_t msg_data[1];
|
||||
|
||||
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 */
|
||||
@ -158,6 +160,8 @@ ipmi_get_user_name(
|
||||
return -1;
|
||||
}
|
||||
if (rsp->ccode > 0) {
|
||||
if (rsp->ccode == 0xcc)
|
||||
return 0;
|
||||
lprintf(LOG_ERR, "Get User Name command failed (user %d): %s",
|
||||
user_id, val2str(rsp->ccode, completion_code_vals));
|
||||
return -1;
|
||||
@ -259,8 +263,8 @@ ipmi_print_user_list(
|
||||
|
||||
|
||||
++current_user_id;
|
||||
} while((current_user_id < user_access.maximum_ids) &&
|
||||
(current_user_id < 63)); /* Absolute maximum allowed by spec */
|
||||
} while((current_user_id <= user_access.maximum_ids) &&
|
||||
(current_user_id <= 63)); /* Absolute maximum allowed by spec */
|
||||
|
||||
|
||||
return 0;
|
||||
@ -345,6 +349,47 @@ ipmi_user_set_username(
|
||||
}
|
||||
|
||||
|
||||
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[17];
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ipmi_user_set_password
|
||||
@ -450,15 +495,16 @@ ipmi_user_test_password(
|
||||
/*
|
||||
* print_user_usage
|
||||
*/
|
||||
void
|
||||
print_user_usage()
|
||||
static void
|
||||
print_user_usage(void)
|
||||
{
|
||||
lprintf(LOG_NOTICE, "User Commands: summary [<channel number>]");
|
||||
lprintf(LOG_NOTICE, " list [<channel number>]");
|
||||
lprintf(LOG_NOTICE, " set name <user id> <username>");
|
||||
lprintf(LOG_NOTICE, " set password <user id> [<password>]");
|
||||
lprintf(LOG_NOTICE, " disable <user id> [<channel number>]");
|
||||
lprintf(LOG_NOTICE, " enable <user id> [<channel number>]");
|
||||
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, " test <user id> <16|20> [<password]>\n");
|
||||
}
|
||||
|
||||
@ -484,8 +530,6 @@ ipmi_user_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
{
|
||||
int retval = 0;
|
||||
|
||||
ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN);
|
||||
|
||||
/*
|
||||
* Help
|
||||
*/
|
||||
@ -702,8 +746,40 @@ 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);
|
||||
return -1;
|
||||
}
|
||||
|
||||
retval = ipmi_user_set_userpriv(intf,channel,user_id,priv_level);
|
||||
}
|
||||
|
||||
/*
|
||||
* Disable / Enable
|
||||
|
@ -143,6 +143,7 @@ void log_halt(void)
|
||||
closelog();
|
||||
|
||||
free(logpriv);
|
||||
logpriv = NULL;
|
||||
}
|
||||
|
||||
int log_level_get(void)
|
||||
|
@ -40,12 +40,8 @@ MAINTAINERCLEANFILES = Makefile.in
|
||||
ipmitool_SOURCES = ipmitool.c ipmishell.c
|
||||
ipmitool_LDADD = $(top_builddir)/lib/libipmitool.la plugins/libintf.la
|
||||
|
||||
if IPMIEVD
|
||||
ipmievd_SOURCES = ipmievd.c
|
||||
ipmievd_LDADD = $(top_builddir)/lib/libipmitool.la plugins/libintf.la
|
||||
endif
|
||||
|
||||
EXTRA_DIST = ipmievd.c
|
||||
|
||||
bin_PROGRAMS = ipmitool @IPMIEVD_BIN@
|
||||
EXTRA_PROGRAMS = ipmitool ipmievd
|
||||
bin_PROGRAMS = ipmitool
|
||||
sbin_PROGRAMS = ipmievd
|
||||
|
@ -44,94 +44,258 @@
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/poll.h>
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <signal.h>
|
||||
#include <paths.h>
|
||||
# include <signal.h>
|
||||
# include <paths.h>
|
||||
#endif
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#ifdef HAVE_OPENIPMI_H
|
||||
#ifdef IPMI_INTF_OPEN
|
||||
# ifdef HAVE_OPENIPMI_H
|
||||
# include <linux/compiler.h>
|
||||
# include <linux/ipmi.h>
|
||||
#else
|
||||
# include <sys/poll.h>
|
||||
# else /* HAVE_OPENIPMI_H */
|
||||
# include "plugins/open/open.h"
|
||||
#endif
|
||||
# include <sys/poll.h>
|
||||
# endif /* HAVE_OPENIPMI_H */
|
||||
#endif /* IPMI_INTF_OPEN */
|
||||
|
||||
#include <ipmitool/helper.h>
|
||||
#include <ipmitool/log.h>
|
||||
#include <ipmitool/ipmi.h>
|
||||
#include <ipmitool/ipmi_intf.h>
|
||||
#include <ipmitool/ipmi_sel.h>
|
||||
#include <ipmitool/ipmi_sdr.h>
|
||||
#include <ipmitool/ipmi_strings.h>
|
||||
#include <ipmitool/ipmi_main.h>
|
||||
|
||||
extern int errno;
|
||||
/* global variables */
|
||||
int verbose = 0;
|
||||
int csv_output = 0;
|
||||
uint16_t selwatch_count = 0; /* number of entries in the SEL */
|
||||
uint16_t selwatch_lastid = 0; /* current last entry in the SEL */
|
||||
int selwatch_timeout = 10; /* default to 10 seconds */
|
||||
|
||||
static void daemonize(void)
|
||||
/* event interface definition */
|
||||
struct ipmi_event_intf {
|
||||
char name[16];
|
||||
char desc[128];
|
||||
int (*setup)(struct ipmi_event_intf * eintf);
|
||||
int (*wait)(struct ipmi_event_intf * eintf);
|
||||
int (*read)(struct ipmi_event_intf * eintf);
|
||||
int (*check)(struct ipmi_event_intf * eintf);
|
||||
void (*log)(struct ipmi_event_intf * eintf, struct sel_event_record * evt);
|
||||
struct ipmi_intf * intf;
|
||||
};
|
||||
|
||||
static void log_event(struct ipmi_event_intf * eintf, struct sel_event_record * evt);
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~ openipmi ~~~~~~~~~~~~~~~~~~~~ */
|
||||
#ifdef IPMI_INTF_OPEN
|
||||
static int openipmi_setup(struct ipmi_event_intf * eintf);
|
||||
static int openipmi_wait(struct ipmi_event_intf * eintf);
|
||||
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",
|
||||
setup: openipmi_setup,
|
||||
wait: openipmi_wait,
|
||||
read: openipmi_read,
|
||||
log: log_event,
|
||||
};
|
||||
#endif
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~ selwatch ~~~~~~~~~~~~~~~~~~~~ */
|
||||
static int selwatch_setup(struct ipmi_event_intf * eintf);
|
||||
static int selwatch_wait(struct ipmi_event_intf * eintf);
|
||||
static int selwatch_read(struct ipmi_event_intf * eintf);
|
||||
static int selwatch_check(struct ipmi_event_intf * eintf);
|
||||
static struct ipmi_event_intf selwatch_event_intf = {
|
||||
name: "sel",
|
||||
desc: "Poll SEL for notification of events",
|
||||
setup: selwatch_setup,
|
||||
wait: selwatch_wait,
|
||||
read: selwatch_read,
|
||||
check: selwatch_check,
|
||||
log: log_event,
|
||||
};
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
struct ipmi_event_intf * ipmi_event_intf_table[] = {
|
||||
#ifdef IPMI_INTF_OPEN
|
||||
&openipmi_event_intf,
|
||||
#endif
|
||||
&selwatch_event_intf,
|
||||
NULL
|
||||
};
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static void
|
||||
ipmievd_usage(void)
|
||||
{
|
||||
pid_t pid;
|
||||
int fd;
|
||||
#ifdef SIGHUP
|
||||
sigset_t sighup;
|
||||
#endif
|
||||
|
||||
/* if we are started from init no need to become daemon */
|
||||
if (getppid() == 1)
|
||||
return;
|
||||
|
||||
#ifdef SIGHUP
|
||||
sigemptyset(&sighup);
|
||||
sigaddset(&sighup, SIGHUP);
|
||||
if (sigprocmask(SIG_UNBLOCK, &sighup, NULL) < 0)
|
||||
fprintf(stderr, "ERROR: could not unblock SIGHUP signal\n");
|
||||
signal(SIGHUP, SIG_IGN);
|
||||
#endif
|
||||
#ifdef SIGTTOU
|
||||
signal(SIGTTOU, SIG_IGN);
|
||||
#endif
|
||||
#ifdef SIGTTIN
|
||||
signal(SIGTTIN, SIG_IGN);
|
||||
#endif
|
||||
#ifdef SIGQUIT
|
||||
signal(SIGQUIT, SIG_IGN);
|
||||
#endif
|
||||
#ifdef SIGTSTP
|
||||
signal(SIGTSTP, SIG_IGN);
|
||||
#endif
|
||||
|
||||
pid = (pid_t) fork();
|
||||
if (pid < 0 || pid > 0)
|
||||
exit(0);
|
||||
|
||||
#if defined(SIGTSTP) && defined(TIOCNOTTY)
|
||||
if (setpgid(0, getpid()) == -1)
|
||||
exit(1);
|
||||
if ((fd = open(_PATH_TTY, O_RDWR)) >= 0) {
|
||||
ioctl(fd, TIOCNOTTY, NULL);
|
||||
close(fd);
|
||||
}
|
||||
#else
|
||||
if (setpgrp() == -1)
|
||||
exit(1);
|
||||
pid = (pid_t) fork();
|
||||
if (pid < 0 || pid > 0)
|
||||
exit(0);
|
||||
#endif
|
||||
|
||||
chdir("/");
|
||||
umask(0);
|
||||
|
||||
for (fd=0; fd<64; fd++)
|
||||
close(fd);
|
||||
|
||||
open("/dev/null", O_RDWR);
|
||||
dup(0);
|
||||
dup(0);
|
||||
lprintf(LOG_NOTICE, "Options:");
|
||||
lprintf(LOG_NOTICE, "\ttimeout=# Time between checks for SEL polling method [default=10]");
|
||||
lprintf(LOG_NOTICE, "\tdaemon Become a daemon [default]");
|
||||
lprintf(LOG_NOTICE, "\tnodaemon Do NOT become a daemon");
|
||||
}
|
||||
|
||||
static int enable_event_msg_buffer(struct ipmi_intf * intf)
|
||||
/* ipmi_intf_load - Load an event interface from the table above
|
||||
* If no interface name is given return first entry
|
||||
*
|
||||
* @name: interface name to try and load
|
||||
*
|
||||
* returns pointer to inteface structure if found
|
||||
* returns NULL on error
|
||||
*/
|
||||
static struct ipmi_event_intf *
|
||||
ipmi_event_intf_load(char * name)
|
||||
{
|
||||
struct ipmi_event_intf ** intf;
|
||||
struct ipmi_event_intf * i;
|
||||
|
||||
if (name == NULL) {
|
||||
i = ipmi_event_intf_table[0];
|
||||
return i;
|
||||
}
|
||||
|
||||
for (intf = ipmi_event_intf_table;
|
||||
((intf != NULL) && (*intf != NULL));
|
||||
intf++) {
|
||||
i = *intf;
|
||||
if (strncmp(name, i->name, strlen(name)) == 0) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
log_event(struct ipmi_event_intf * eintf, struct sel_event_record * evt)
|
||||
{
|
||||
char *desc;
|
||||
const char *type;
|
||||
struct sdr_record_list * sdr;
|
||||
struct ipmi_intf * intf = eintf->intf;
|
||||
float trigger_reading = 0.0;
|
||||
float threshold_reading = 0.0;
|
||||
|
||||
if (evt == NULL)
|
||||
return;
|
||||
|
||||
if (evt->record_type == 0xf0) {
|
||||
lprintf(LOG_ALERT, "Linux kernel panic: %.11s", (char *) evt + 5);
|
||||
return;
|
||||
}
|
||||
else if (evt->record_type >= 0xc0) {
|
||||
lprintf(LOG_NOTICE, "IPMI Event OEM Record %02x", 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]);
|
||||
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);
|
||||
if (sdr == NULL) {
|
||||
/* could not find matching SDR record */
|
||||
if (desc) {
|
||||
lprintf(LOG_NOTICE, "%s sensor - %s",
|
||||
type, desc);
|
||||
free(desc);
|
||||
} else {
|
||||
lprintf(LOG_NOTICE, "%s sensor %02x",
|
||||
type, evt->sel_type.standard_type.sensor_num);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
switch (sdr->type) {
|
||||
case SDR_RECORD_TYPE_FULL_SENSOR:
|
||||
if (evt->sel_type.standard_type.event_type == 1) {
|
||||
/*
|
||||
* Threshold Event
|
||||
*/
|
||||
|
||||
/* trigger reading in event data byte 2 */
|
||||
if (((evt->sel_type.standard_type.event_data[0] >> 6) & 3) == 1) {
|
||||
trigger_reading = sdr_convert_sensor_reading(
|
||||
sdr->record.full, evt->sel_type.standard_type.event_data[1]);
|
||||
}
|
||||
|
||||
/* trigger threshold in event data byte 3 */
|
||||
if (((evt->sel_type.standard_type.event_data[0] >> 4) & 3) == 1) {
|
||||
threshold_reading = sdr_convert_sensor_reading(
|
||||
sdr->record.full, evt->sel_type.standard_type.event_data[2]);
|
||||
}
|
||||
|
||||
lprintf(LOG_NOTICE, "%s sensor %s %s (Reading %.*f %s Threshold %.*f %s)",
|
||||
type,
|
||||
sdr->record.full->id_string,
|
||||
desc ? : "",
|
||||
(trigger_reading==(int)trigger_reading) ? 0 : 2,
|
||||
trigger_reading,
|
||||
((evt->sel_type.standard_type.event_data[0] & 0xf) % 2) ? ">" : "<",
|
||||
(threshold_reading==(int)threshold_reading) ? 0 : 2,
|
||||
threshold_reading,
|
||||
ipmi_sdr_get_unit_string(sdr->record.full->unit.modifier,
|
||||
sdr->record.full->unit.type.base,
|
||||
sdr->record.full->unit.type.modifier));
|
||||
}
|
||||
else if ((evt->sel_type.standard_type.event_type >= 0x2 && evt->sel_type.standard_type.event_type <= 0xc) ||
|
||||
(evt->sel_type.standard_type.event_type == 0x6f)) {
|
||||
/*
|
||||
* Discrete Event
|
||||
*/
|
||||
lprintf(LOG_NOTICE, "%s sensor %s %s",
|
||||
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 */
|
||||
}
|
||||
}
|
||||
else if (evt->sel_type.standard_type.event_type >= 0x70 && evt->sel_type.standard_type.event_type <= 0x7f) {
|
||||
/*
|
||||
* OEM Event
|
||||
*/
|
||||
lprintf(LOG_NOTICE, "%s sensor %s %s",
|
||||
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",
|
||||
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 ? : "");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
lprintf(LOG_NOTICE, "%s sensor - %s",
|
||||
type, evt->sel_type.standard_type.sensor_num, desc ? : "");
|
||||
break;
|
||||
}
|
||||
|
||||
if (desc)
|
||||
free(desc);
|
||||
}
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/** OpenIPMI Functions **/
|
||||
/*************************************************************************/
|
||||
#ifdef IPMI_INTF_OPEN
|
||||
static int
|
||||
openipmi_enable_event_msg_buffer(struct ipmi_intf * intf)
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
@ -143,9 +307,13 @@ static int enable_event_msg_buffer(struct ipmi_intf * intf)
|
||||
req.msg.cmd = 0x2f; /* Get BMC Global Enables */
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (!rsp || rsp->ccode) {
|
||||
lprintf(LOG_WARNING, "Get BMC Global Enables command filed [ccode %02x]",
|
||||
rsp ? rsp->ccode : 0);
|
||||
if (rsp == NULL) {
|
||||
lprintf(LOG_ERR, "Get BMC Global Enables command failed");
|
||||
return -1;
|
||||
}
|
||||
else if (rsp->ccode > 0) {
|
||||
lprintf(LOG_ERR, "Get BMC Global Enables command failed: %s",
|
||||
val2str(rsp->ccode, completion_code_vals));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -155,9 +323,13 @@ static int enable_event_msg_buffer(struct ipmi_intf * intf)
|
||||
req.msg.data_len = 1;
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (!rsp || rsp->ccode) {
|
||||
lprintf(LOG_WARNING, "Set BMC Global Enables command failed [ccode %02x]",
|
||||
rsp ? rsp->ccode : 0);
|
||||
if (rsp == NULL) {
|
||||
lprintf(LOG_ERR, "Set BMC Global Enables command failed");
|
||||
return -1;
|
||||
}
|
||||
else if (rsp->ccode > 0) {
|
||||
lprintf(LOG_ERR, "Set BMC Global Enables command failed: %s",
|
||||
val2str(rsp->ccode, completion_code_vals));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -166,29 +338,33 @@ static int enable_event_msg_buffer(struct ipmi_intf * intf)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void log_event(struct sel_event_record * evt)
|
||||
static int
|
||||
openipmi_setup(struct ipmi_event_intf * eintf)
|
||||
{
|
||||
char *desc;
|
||||
int i, r;
|
||||
|
||||
if (!evt)
|
||||
return;
|
||||
/* enable event message buffer */
|
||||
lprintf(LOG_DEBUG, "Enabling event message buffer");
|
||||
r = openipmi_enable_event_msg_buffer(eintf->intf);
|
||||
if (r < 0) {
|
||||
lprintf(LOG_ERR, "Could not enable event message buffer");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (evt->record_type == 0xf0)
|
||||
lprintf(LOG_ALERT, "Linux kernel panic: %.11s", (char *) evt + 5);
|
||||
else if (evt->record_type >= 0xc0)
|
||||
lprintf(LOG_NOTICE, "IPMI Event OEM Record %02x", evt->record_type);
|
||||
else {
|
||||
ipmi_get_event_desc(evt, &desc);
|
||||
if (desc) {
|
||||
lprintf(LOG_NOTICE, "%s Sensor %02x - %s",
|
||||
ipmi_sel_get_sensor_type(evt->sensor_type),
|
||||
evt->sensor_num, desc);
|
||||
free(desc);
|
||||
}
|
||||
/* enable OpenIPMI event receiver */
|
||||
lprintf(LOG_DEBUG, "Enabling event receiver");
|
||||
i = 1;
|
||||
r = ioctl(eintf->intf->fd, IPMICTL_SET_GETS_EVENTS_CMD, &i);
|
||||
if (r != 0) {
|
||||
lperror(LOG_ERR, "Could not enable event receiver");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void read_event(struct ipmi_intf * intf)
|
||||
static int
|
||||
openipmi_read(struct ipmi_event_intf * eintf)
|
||||
{
|
||||
struct ipmi_addr addr;
|
||||
struct ipmi_recv recv;
|
||||
@ -200,126 +376,45 @@ static void read_event(struct ipmi_intf * intf)
|
||||
recv.msg.data = data;
|
||||
recv.msg.data_len = sizeof(data);
|
||||
|
||||
rv = ioctl(intf->fd, IPMICTL_RECEIVE_MSG_TRUNC, &recv);
|
||||
rv = ioctl(eintf->intf->fd, IPMICTL_RECEIVE_MSG_TRUNC, &recv);
|
||||
if (rv < 0) {
|
||||
switch (errno) {
|
||||
case EINTR:
|
||||
return; /* abort */
|
||||
return 0; /* abort */
|
||||
case EMSGSIZE:
|
||||
recv.msg.data_len = sizeof(data); /* truncated */
|
||||
break;
|
||||
default:
|
||||
lperror(LOG_ERR, "Unable to receive IPMI message");
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!recv.msg.data || recv.msg.data_len == 0) {
|
||||
lprintf(LOG_ERR, "No data in event");
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
if (recv.recv_type != IPMI_ASYNC_EVENT_RECV_TYPE) {
|
||||
lprintf(LOG_ERR, "Type %x is not an event", recv.recv_type);
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
lprintf(LOG_DEBUG, "netfn:%x cmd:%x ccode:%d",
|
||||
recv.msg.netfn, recv.msg.cmd, recv.msg.data[0]);
|
||||
|
||||
log_event((struct sel_event_record *)recv.msg.data);
|
||||
eintf->log(eintf, (struct sel_event_record *)recv.msg.data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_exit(struct ipmi_intf * intf, int rv)
|
||||
static int
|
||||
openipmi_wait(struct ipmi_event_intf * eintf)
|
||||
{
|
||||
if (intf)
|
||||
intf->close(intf);
|
||||
log_halt();
|
||||
exit(rv);
|
||||
}
|
||||
|
||||
static void usage(void)
|
||||
{
|
||||
fprintf(stderr, "usage: ipmievd [-hvd]\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " -h This help\n");
|
||||
fprintf(stderr, " -v Verbose (can use multiple times)\n");
|
||||
fprintf(stderr, " -s Do NOT daemonize\n");
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
int main(int argc, char ** argv)
|
||||
{
|
||||
struct ipmi_intf * intf;
|
||||
int r, a;
|
||||
int i = 1;
|
||||
int daemon = 1;
|
||||
struct pollfd pfd;
|
||||
|
||||
/* make sure we have UID 0 */
|
||||
if (geteuid() || getuid()) {
|
||||
fprintf(stderr, "Inadequate privledges\n");
|
||||
do_exit(NULL, EXIT_FAILURE);
|
||||
}
|
||||
|
||||
while ((a = getopt(argc, (char **)argv, "hvs")) != -1) {
|
||||
switch (a) {
|
||||
case 'h':
|
||||
usage();
|
||||
do_exit(NULL, EXIT_SUCCESS);
|
||||
break;
|
||||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
case 's':
|
||||
daemon = 0;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
do_exit(NULL, EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if (daemon)
|
||||
daemonize();
|
||||
|
||||
log_init("ipmievd", daemon, verbose);
|
||||
|
||||
/* load interface */
|
||||
lprintf(LOG_DEBUG, "Loading OpenIPMI interface");
|
||||
intf = ipmi_intf_load("open");
|
||||
if (!intf) {
|
||||
lprintf(LOG_ERR, "Unable to load OpenIPMI interface");
|
||||
do_exit(NULL, EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* open connection to openipmi device */
|
||||
lprintf(LOG_DEBUG, "Connecting to OpenIPMI device");
|
||||
r = intf->open(intf);
|
||||
if (r < 0) {
|
||||
lprintf(LOG_ERR, "Unable to open OpenIPMI device");
|
||||
do_exit(NULL, EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* enable event message buffer */
|
||||
lprintf(LOG_DEBUG, "Enabling event message buffer");
|
||||
r = enable_event_msg_buffer(intf);
|
||||
if (r < 0) {
|
||||
lprintf(LOG_ERR, "Could not enable event message buffer");
|
||||
do_exit(intf, EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* enable OpenIPMI event receiver */
|
||||
lprintf(LOG_DEBUG, "Enabling event receiver");
|
||||
r = ioctl(intf->fd, IPMICTL_SET_GETS_EVENTS_CMD, &i);
|
||||
if (r != 0) {
|
||||
lperror(LOG_ERR, "Could not enable event receiver");
|
||||
do_exit(intf, EXIT_FAILURE);
|
||||
}
|
||||
|
||||
lprintf(LOG_NOTICE, "Waiting for events...");
|
||||
int r;
|
||||
|
||||
for (;;) {
|
||||
pfd.fd = intf->fd; /* wait on openipmi device */
|
||||
pfd.fd = eintf->intf->fd; /* wait on openipmi device */
|
||||
pfd.events = POLLIN; /* wait for input */
|
||||
r = poll(&pfd, 1, -1);
|
||||
|
||||
@ -329,14 +424,284 @@ int main(int argc, char ** argv)
|
||||
break;
|
||||
case -1:
|
||||
lperror(LOG_CRIT, "Unable to read from IPMI device");
|
||||
do_exit(intf, EXIT_FAILURE);
|
||||
break;
|
||||
return -1;
|
||||
default:
|
||||
if (pfd.revents && POLLIN)
|
||||
read_event(intf);
|
||||
if (pfd.revents & POLLIN)
|
||||
eintf->read(eintf);
|
||||
}
|
||||
}
|
||||
|
||||
lprintf(LOG_DEBUG, "Shutting down...");
|
||||
do_exit(intf, EXIT_SUCCESS);
|
||||
return 0;
|
||||
}
|
||||
#endif /* IPMI_INTF_OPEN */
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/** SEL Watch Functions **/
|
||||
/*************************************************************************/
|
||||
static uint16_t
|
||||
selwatch_get_count(struct ipmi_intf * intf)
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.msg.netfn = IPMI_NETFN_STORAGE;
|
||||
req.msg.cmd = IPMI_CMD_GET_SEL_INFO;
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (rsp == NULL) {
|
||||
lprintf(LOG_ERR, "Get SEL Info command failed");
|
||||
return 0;
|
||||
}
|
||||
if (rsp->ccode > 0) {
|
||||
lprintf(LOG_ERR, "Get SEL Info command failed: %s",
|
||||
val2str(rsp->ccode, completion_code_vals));
|
||||
return 0;
|
||||
}
|
||||
|
||||
lprintf(LOG_DEBUG, "SEL count is %d", buf2short(rsp->data+1));
|
||||
return buf2short(rsp->data+1);
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
selwatch_get_lastid(struct ipmi_intf * intf)
|
||||
{
|
||||
int next_id = 0;
|
||||
uint16_t curr_id = 0;
|
||||
struct sel_event_record evt;
|
||||
|
||||
if (selwatch_count == 0)
|
||||
return 0;
|
||||
|
||||
while (next_id != 0xffff) {
|
||||
curr_id = next_id;
|
||||
lprintf(LOG_DEBUG, "SEL Next ID: %04x", curr_id);
|
||||
|
||||
next_id = ipmi_sel_get_std_entry(intf, curr_id, &evt);
|
||||
if (next_id < 0)
|
||||
break;
|
||||
if (next_id == 0) {
|
||||
/*
|
||||
* usually next_id of zero means end but
|
||||
* retry because some hardware has quirks
|
||||
* and will return 0 randomly.
|
||||
*/
|
||||
next_id = ipmi_sel_get_std_entry(intf, curr_id, &evt);
|
||||
if (next_id <= 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
lprintf(LOG_DEBUG, "SEL lastid is %04x", curr_id);
|
||||
|
||||
return curr_id;
|
||||
}
|
||||
|
||||
static int
|
||||
selwatch_setup(struct ipmi_event_intf * eintf)
|
||||
{
|
||||
/* save current sel record count */
|
||||
selwatch_count = selwatch_get_count(eintf->intf);
|
||||
lprintf(LOG_DEBUG, "Current SEL count is %d", selwatch_count);
|
||||
|
||||
/* save current last record ID */
|
||||
selwatch_lastid = selwatch_get_lastid(eintf->intf);
|
||||
lprintf(LOG_DEBUG, "Current SEL lastid is %04x", selwatch_lastid);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* selwatch_check - check for waiting events
|
||||
*
|
||||
* this is done by reading sel info and comparing
|
||||
* the sel count value to what we currently know
|
||||
*/
|
||||
static int
|
||||
selwatch_check(struct ipmi_event_intf * eintf)
|
||||
{
|
||||
uint16_t old_count = selwatch_count;
|
||||
selwatch_count = selwatch_get_count(eintf->intf);
|
||||
if (selwatch_count == 0) {
|
||||
lprintf(LOG_DEBUG, "SEL count is 0 (old=%d), resetting lastid to 0", old_count);
|
||||
selwatch_lastid = 0;
|
||||
} else if (selwatch_count < old_count) {
|
||||
selwatch_lastid = selwatch_get_lastid(eintf->intf);
|
||||
lprintf(LOG_DEBUG, "SEL count lowered, new SEL lastid is %04x", selwatch_lastid);
|
||||
}
|
||||
return (selwatch_count > old_count);
|
||||
}
|
||||
|
||||
static int
|
||||
selwatch_read(struct ipmi_event_intf * eintf)
|
||||
{
|
||||
uint16_t curr_id = 0;
|
||||
int next_id = selwatch_lastid;
|
||||
struct sel_event_record evt;
|
||||
|
||||
if (selwatch_count == 0)
|
||||
return -1;
|
||||
|
||||
while (next_id != 0xffff) {
|
||||
curr_id = next_id;
|
||||
lprintf(LOG_DEBUG, "SEL Read ID: %04x", curr_id);
|
||||
|
||||
next_id = ipmi_sel_get_std_entry(eintf->intf, curr_id, &evt);
|
||||
if (next_id < 0)
|
||||
break;
|
||||
if (next_id == 0) {
|
||||
/*
|
||||
* usually next_id of zero means end but
|
||||
* retry because some hardware has quirks
|
||||
* and will return 0 randomly.
|
||||
*/
|
||||
next_id = ipmi_sel_get_std_entry(eintf->intf, curr_id, &evt);
|
||||
if (next_id <= 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (curr_id != selwatch_lastid)
|
||||
eintf->log(eintf, &evt);
|
||||
else if (curr_id == 0)
|
||||
eintf->log(eintf, &evt);
|
||||
}
|
||||
|
||||
selwatch_lastid = curr_id;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
selwatch_wait(struct ipmi_event_intf * eintf)
|
||||
{
|
||||
for (;;) {
|
||||
if (eintf->check(eintf) > 0) {
|
||||
lprintf(LOG_DEBUG, "New Events");
|
||||
eintf->read(eintf);
|
||||
}
|
||||
sleep(selwatch_timeout);
|
||||
}
|
||||
}
|
||||
/*************************************************************************/
|
||||
|
||||
int
|
||||
ipmievd_main(struct ipmi_event_intf * eintf, int argc, char ** argv)
|
||||
{
|
||||
int i, rc;
|
||||
int daemon = 1;
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
if (strncasecmp(argv[i], "help", 4) == 0) {
|
||||
ipmievd_usage();
|
||||
return 0;
|
||||
}
|
||||
if (strncasecmp(argv[i], "daemon", 6) == 0) {
|
||||
daemon = 1;
|
||||
}
|
||||
else if (strncasecmp(argv[i], "nodaemon", 8) == 0) {
|
||||
daemon = 0;
|
||||
}
|
||||
else if (strncasecmp(argv[i], "daemon=", 7) == 0) {
|
||||
if (strncasecmp(argv[i]+7, "on", 2) == 0 ||
|
||||
strncasecmp(argv[i]+7, "yes", 3) == 0)
|
||||
daemon = 1;
|
||||
else if (strncasecmp(argv[i]+7, "off", 3) == 0 ||
|
||||
strncasecmp(argv[i]+7, "no", 2) == 0)
|
||||
daemon = 0;
|
||||
}
|
||||
else if (strncasecmp(argv[i], "timeout=", 8) == 0) {
|
||||
selwatch_timeout = strtoul(argv[i]+8, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (daemon)
|
||||
ipmi_start_daemon();
|
||||
|
||||
log_halt();
|
||||
log_init("ipmievd", daemon, verbose);
|
||||
|
||||
/* generate SDR cache for fast lookups */
|
||||
lprintf(LOG_NOTICE, "Reading sensors...");
|
||||
ipmi_sdr_list_cache(eintf->intf);
|
||||
lprintf(LOG_DEBUG, "Sensors cached");
|
||||
|
||||
/* call event handler setup routine */
|
||||
if (eintf->setup != NULL) {
|
||||
rc = eintf->setup(eintf);
|
||||
if (rc < 0) {
|
||||
lprintf(LOG_ERR, "Error setting up Event Interface %s", eintf->name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
lprintf(LOG_NOTICE, "Waiting for events...");
|
||||
|
||||
/* now launch event wait loop */
|
||||
if (eintf->wait != NULL) {
|
||||
rc = eintf->wait(eintf);
|
||||
if (rc < 0) {
|
||||
lprintf(LOG_ERR, "Error waiting for events!");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ipmievd_sel_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
{
|
||||
struct ipmi_event_intf * eintf;
|
||||
|
||||
eintf = ipmi_event_intf_load("sel");
|
||||
if (eintf == NULL) {
|
||||
lprintf(LOG_ERR, "Unable to load event interface");
|
||||
return -1;
|
||||
}
|
||||
|
||||
eintf->intf = intf;
|
||||
|
||||
return ipmievd_main(eintf, argc, argv);
|
||||
}
|
||||
|
||||
int
|
||||
ipmievd_open_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
{
|
||||
struct ipmi_event_intf * eintf;
|
||||
|
||||
/* only one interface works for this */
|
||||
if (strncmp(intf->name, "open", 4) != 0) {
|
||||
lprintf(LOG_ERR, "Invalid Interface for OpenIPMI Event Handler: %s", intf->name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
eintf = ipmi_event_intf_load("open");
|
||||
if (eintf == NULL) {
|
||||
lprintf(LOG_ERR, "Unable to load event interface");
|
||||
return -1;
|
||||
}
|
||||
|
||||
eintf->intf = intf;
|
||||
|
||||
return ipmievd_main(eintf, argc, argv);
|
||||
}
|
||||
|
||||
struct ipmi_cmd ipmievd_cmd_list[] = {
|
||||
#ifdef IPMI_INTF_OPEN
|
||||
{ ipmievd_open_main, "open", "Use OpenIPMI for asyncronous notification of events" },
|
||||
#endif
|
||||
{ ipmievd_sel_main, "sel", "Poll SEL for notification of events" },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
int main(int argc, char ** argv)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = ipmi_main(argc, argv, ipmievd_cmd_list, NULL);
|
||||
|
||||
if (rc < 0)
|
||||
exit(EXIT_FAILURE);
|
||||
else
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
@ -46,6 +46,7 @@
|
||||
#include <ipmitool/ipmi.h>
|
||||
#include <ipmitool/ipmi_intf.h>
|
||||
#include <ipmitool/ipmi_session.h>
|
||||
#include <ipmitool/ipmi_main.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
@ -54,9 +55,6 @@
|
||||
#define EXEC_BUF_SIZE 1024
|
||||
#define EXEC_ARG_SIZE 32
|
||||
|
||||
extern void ipmi_cmd_print(void);
|
||||
extern int ipmi_cmd_run(struct ipmi_intf * intf, char * name, int argc, char ** argv);
|
||||
|
||||
extern const struct valstr ipmi_privlvl_vals[];
|
||||
extern const struct valstr ipmi_authtype_session_vals[];
|
||||
|
||||
@ -98,7 +96,7 @@ static int rl_event_keepalive(void)
|
||||
|
||||
int ipmi_shell_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
{
|
||||
char *pbuf, **ap, *__argv[20];
|
||||
char *ptr, *pbuf, **ap, *__argv[20];
|
||||
int __argc, rc=0;
|
||||
|
||||
rl_readline_name = "ipmitool";
|
||||
@ -113,8 +111,9 @@ 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
|
||||
/* set to 1 second */
|
||||
rl_set_keyboard_input_timeout(1000*1000);
|
||||
/* There is a bug in readline 4.2 and later (at least on FreeBSD):
|
||||
* timeout equal or greater than 1 second causes an infinite loop. */
|
||||
rl_set_keyboard_input_timeout(1000 * 1000 - 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -130,7 +129,7 @@ int ipmi_shell_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
}
|
||||
if (strncmp(pbuf, "help", 4) == 0 ||
|
||||
strncmp(pbuf, "?", 1) == 0) {
|
||||
ipmi_cmd_print();
|
||||
ipmi_cmd_print(intf->cmdlist);
|
||||
free(pbuf);
|
||||
continue;
|
||||
}
|
||||
@ -138,6 +137,28 @@ 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))
|
||||
*ptr = '~';
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
if (*ptr == '\'') {
|
||||
ptr++;
|
||||
while (*ptr != '\'') {
|
||||
if (isspace(*ptr))
|
||||
*ptr = '~';
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
ptr++;
|
||||
}
|
||||
|
||||
__argc = 0;
|
||||
ap = __argv;
|
||||
|
||||
@ -145,6 +166,27 @@ int ipmi_shell_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
*ap != NULL;
|
||||
*ap = strtok(NULL, " \t")) {
|
||||
__argc++;
|
||||
|
||||
ptr = *ap;
|
||||
if (*ptr == '\'') {
|
||||
memmove(ptr, ptr+1, strlen(ptr));
|
||||
while (*ptr != '\'') {
|
||||
if (*ptr == '~')
|
||||
*ptr = ' ';
|
||||
ptr++;
|
||||
}
|
||||
*ptr = '\0';
|
||||
}
|
||||
if (*ptr == '"') {
|
||||
memmove(ptr, ptr+1, strlen(ptr));
|
||||
while (*ptr != '"') {
|
||||
if (*ptr == '~')
|
||||
*ptr = ' ';
|
||||
ptr++;
|
||||
}
|
||||
*ptr = '\0';
|
||||
}
|
||||
|
||||
if (**ap != '\0') {
|
||||
if (++ap >= &__argv[20])
|
||||
break;
|
||||
@ -173,6 +215,16 @@ ipmi_shell_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
|
||||
#endif /* HAVE_READLINE */
|
||||
|
||||
int ipmi_echo_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<argc; i++) {
|
||||
printf("%s ", argv[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static void
|
||||
ipmi_set_usage(void)
|
||||
{
|
||||
@ -230,19 +282,27 @@ int ipmi_set_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
printf("Set session password\n");
|
||||
}
|
||||
else if (strncmp(argv[0], "authtype", 8) == 0) {
|
||||
uint8_t authtype;
|
||||
authtype = (uint8_t)str2val(argv[1], ipmi_authtype_session_vals);
|
||||
int authtype;
|
||||
authtype = str2val(argv[1], ipmi_authtype_session_vals);
|
||||
if (authtype == 0xFF) {
|
||||
lprintf(LOG_ERR, "Invalid authtype: %s", argv[1]);
|
||||
} else {
|
||||
ipmi_intf_session_set_authtype(intf, authtype);
|
||||
printf("Set session authtype to %s\n",
|
||||
val2str(intf->session->authtype_set, ipmi_authtype_session_vals));
|
||||
}
|
||||
}
|
||||
else if (strncmp(argv[0], "privlvl", 7) == 0) {
|
||||
uint8_t privlvl;
|
||||
privlvl = (uint8_t)str2val(argv[1], ipmi_privlvl_vals);
|
||||
int privlvl;
|
||||
privlvl = str2val(argv[1], ipmi_privlvl_vals);
|
||||
if (privlvl == 0xFF) {
|
||||
lprintf(LOG_ERR, "Invalid privilege level: %s", argv[1]);
|
||||
} else {
|
||||
ipmi_intf_session_set_privlvl(intf, privlvl);
|
||||
printf("Set session privilege level to %s\n",
|
||||
val2str(intf->session->privlvl, ipmi_privlvl_vals));
|
||||
}
|
||||
}
|
||||
else if (strncmp(argv[0], "port", 4) == 0) {
|
||||
int port = atoi(argv[1]);
|
||||
ipmi_intf_session_set_port(intf, port);
|
||||
@ -267,7 +327,7 @@ int ipmi_exec_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
{
|
||||
FILE * fp;
|
||||
char buf[EXEC_BUF_SIZE];
|
||||
char * ptr, * tok, * ret;
|
||||
char * ptr, * tok, * ret, * tmp;
|
||||
int __argc, i, r;
|
||||
char * __argv[EXEC_ARG_SIZE];
|
||||
int rc=0;
|
||||
@ -293,6 +353,28 @@ int ipmi_exec_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
else
|
||||
ptr = buf + strlen(buf);
|
||||
|
||||
/* change "" and '' with spaces in the middle to ~ */
|
||||
ptr = buf;
|
||||
while (*ptr != '\0') {
|
||||
if (*ptr == '"') {
|
||||
ptr++;
|
||||
while (*ptr != '"') {
|
||||
if (isspace(*ptr))
|
||||
*ptr = '~';
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
if (*ptr == '\'') {
|
||||
ptr++;
|
||||
while (*ptr != '\'') {
|
||||
if (isspace(*ptr))
|
||||
*ptr = '~';
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
ptr++;
|
||||
}
|
||||
|
||||
/* clip off trailing and leading whitespace */
|
||||
ptr--;
|
||||
while (isspace(*ptr) && ptr >= buf)
|
||||
@ -305,16 +387,33 @@ int ipmi_exec_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
|
||||
/* parse it and make argument list */
|
||||
__argc = 0;
|
||||
tok = strtok(ptr, " ");
|
||||
while (tok) {
|
||||
for (tok = strtok(ptr, " "); tok != NULL; tok = strtok(NULL, " ")) {
|
||||
if (__argc < EXEC_ARG_SIZE) {
|
||||
__argv[__argc++] = strdup(tok);
|
||||
if (__argv[__argc-1] == NULL) {
|
||||
lprintf(LOG_ERR, "ipmitool: malloc failure");
|
||||
return -1;
|
||||
}
|
||||
tmp = __argv[__argc-1];
|
||||
if (*tmp == '\'') {
|
||||
memmove(tmp, tmp+1, strlen(tmp));
|
||||
while (*tmp != '\'') {
|
||||
if (*tmp == '~')
|
||||
*tmp = ' ';
|
||||
tmp++;
|
||||
}
|
||||
*tmp = '\0';
|
||||
}
|
||||
if (*tmp == '"') {
|
||||
memmove(tmp, tmp+1, strlen(tmp));
|
||||
while (*tmp != '"') {
|
||||
if (*tmp == '~')
|
||||
*tmp = ' ';
|
||||
tmp++;
|
||||
}
|
||||
*tmp = '\0';
|
||||
}
|
||||
}
|
||||
tok = strtok(NULL, " ");
|
||||
}
|
||||
|
||||
/* now run the command, save the result if not successful */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2004 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
@ -37,22 +37,16 @@
|
||||
* facility.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <ipmitool/helper.h>
|
||||
#include <ipmitool/log.h>
|
||||
#include <ipmitool/ipmi.h>
|
||||
#include <ipmitool/ipmi_intf.h>
|
||||
#include <ipmitool/ipmi_session.h>
|
||||
#include <ipmitool/ipmi_main.h>
|
||||
|
||||
#include <ipmitool/ipmi_sdr.h>
|
||||
#include <ipmitool/ipmi_sel.h>
|
||||
#include <ipmitool/ipmi_fru.h>
|
||||
#include <ipmitool/ipmi_sol.h>
|
||||
#include <ipmitool/ipmi_isol.h>
|
||||
#include <ipmitool/ipmi_tsol.h>
|
||||
#include <ipmitool/ipmi_lanp.h>
|
||||
#include <ipmitool/ipmi_chassis.h>
|
||||
#include <ipmitool/ipmi_mc.h>
|
||||
@ -64,471 +58,66 @@
|
||||
#include <ipmitool/ipmi_raw.h>
|
||||
#include <ipmitool/ipmi_pef.h>
|
||||
#include <ipmitool/ipmi_oem.h>
|
||||
#include <ipmitool/ipmi_sunoem.h>
|
||||
#include <ipmitool/ipmi_fwum.h>
|
||||
#include <ipmitool/ipmi_picmg.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef __sun
|
||||
# define OPTION_STRING "I:hVvcH:f:U:p:"
|
||||
#else
|
||||
# define OPTION_STRING "I:hVvcgsEao:H:P:f:U:p:L:A:t:m:"
|
||||
#ifdef HAVE_READLINE
|
||||
extern int ipmi_shell_main(struct ipmi_intf * intf, int argc, char ** argv);
|
||||
#endif
|
||||
extern int ipmi_echo_main(struct ipmi_intf * intf, int argc, char ** argv);
|
||||
extern int ipmi_set_main(struct ipmi_intf * intf, int argc, char ** argv);
|
||||
extern int ipmi_exec_main(struct ipmi_intf * intf, int argc, char ** argv);
|
||||
|
||||
|
||||
int csv_output = 0;
|
||||
int verbose = 0;
|
||||
|
||||
extern const struct valstr ipmi_privlvl_vals[];
|
||||
extern const struct valstr ipmi_authtype_session_vals[];
|
||||
|
||||
/* defined in ipmishell.c */
|
||||
#ifdef HAVE_READLINE
|
||||
extern int ipmi_shell_main(struct ipmi_intf * intf, int argc, char ** argv);
|
||||
#endif
|
||||
extern int ipmi_set_main(struct ipmi_intf * intf, int argc, char ** argv);
|
||||
extern int ipmi_exec_main(struct ipmi_intf * intf, int argc, char ** argv);
|
||||
|
||||
struct ipmi_cmd {
|
||||
int (*func)(struct ipmi_intf * intf, int argc, char ** argv);
|
||||
const char * name;
|
||||
const char * desc;
|
||||
} ipmi_cmd_list[] = {
|
||||
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_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" },
|
||||
{ ipmi_event_main, "event", "Send pre-defined events to MC" },
|
||||
{ ipmi_mc_main, "mc", "Management Controller status and global enables" },
|
||||
{ ipmi_mc_main, "bmc", NULL }, /* for backwards compatibility */
|
||||
{ ipmi_sdr_main, "sdr", "Print Sensor Data Repository entries and readings" },
|
||||
{ ipmi_sensor_main, "sensor", "Print detailed sensor information" },
|
||||
{ ipmi_fru_main, "fru", "Print built-in FRU and scan SDR for FRU locators" },
|
||||
{ ipmi_sel_main, "sel", "Print System Event Log (SEL)" },
|
||||
{ ipmi_pef_main, "pef", "Configure Platform Event Filtering (PEF)" },
|
||||
{ ipmi_sol_main, "sol", "Configure IPMIv2.0 Serial-over-LAN" },
|
||||
{ ipmi_sol_main, "sol", "Configure and connect IPMIv2.0 Serial-over-LAN" },
|
||||
{ ipmi_tsol_main, "tsol", "Configure and connect with Tyan IPMIv1.5 Serial-over-LAN" },
|
||||
{ ipmi_isol_main, "isol", "Configure IPMIv1.5 Serial-over-LAN" },
|
||||
{ ipmi_user_main, "user", "Configure Management Controller users" },
|
||||
{ ipmi_channel_main, "channel", "Configure Management Controller channels" },
|
||||
{ ipmi_session_main, "session", "Print session information" },
|
||||
{ ipmi_sunoem_main, "sunoem", "OEM Commands for Sun servers" },
|
||||
{ ipmi_picmg_main, "picmg", "Run a PICMG/ATCA extended cmd"},
|
||||
{ ipmi_fwum_main, "fwum", "Update IPMC using Kontron OEM Firmware Update Manager" },
|
||||
#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 */
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
/*
|
||||
* Print all the commands in the above table to stderr
|
||||
* used for help text on command line and shell
|
||||
*/
|
||||
void
|
||||
ipmi_cmd_print(void)
|
||||
{
|
||||
struct ipmi_cmd * cmd;
|
||||
lprintf(LOG_NOTICE, "Commands:");
|
||||
for (cmd=ipmi_cmd_list; cmd->func != NULL; cmd++) {
|
||||
if (cmd->desc == NULL)
|
||||
continue;
|
||||
lprintf(LOG_NOTICE, "\t%-12s %s", cmd->name, cmd->desc);
|
||||
}
|
||||
lprintf(LOG_NOTICE, "");
|
||||
}
|
||||
|
||||
/* ipmi_cmd_run - run a command from list based on parameters
|
||||
* called from main()
|
||||
*
|
||||
* 1. iterate through ipmi_cmd_list matching on name
|
||||
* 2. call func() for that command
|
||||
*
|
||||
* @intf: ipmi interface
|
||||
* @name: command name
|
||||
* @argc: command argument count
|
||||
* @argv: command argument list
|
||||
*
|
||||
* returns value from func() of that commnad if found
|
||||
* returns -1 if command is not found
|
||||
*/
|
||||
int
|
||||
ipmi_cmd_run(struct ipmi_intf * intf, char * name, int argc, char ** argv)
|
||||
{
|
||||
struct ipmi_cmd * cmd;
|
||||
|
||||
for (cmd=ipmi_cmd_list; cmd->func != NULL; cmd++) {
|
||||
if (strncmp(name, cmd->name, strlen(cmd->name)) == 0)
|
||||
break;
|
||||
}
|
||||
if (cmd->func == NULL) {
|
||||
lprintf(LOG_ERR, "Invalid command: %s", name);
|
||||
return -1;
|
||||
}
|
||||
return cmd->func(intf, argc, argv);
|
||||
}
|
||||
|
||||
/* ipmitool_usage - print usage help
|
||||
*/
|
||||
static void
|
||||
ipmitool_usage(void)
|
||||
{
|
||||
lprintf(LOG_NOTICE, "ipmitool version %s\n", VERSION);
|
||||
lprintf(LOG_NOTICE, "usage: ipmitool [options...] <command>\n");
|
||||
lprintf(LOG_NOTICE, " -h This help");
|
||||
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, " -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]");
|
||||
lprintf(LOG_NOTICE, " -U username Remote session username");
|
||||
lprintf(LOG_NOTICE, " -f file Read remote session password from file");
|
||||
#ifndef __sun
|
||||
lprintf(LOG_NOTICE, " -L level Remote session privilege level [default=USER]");
|
||||
lprintf(LOG_NOTICE, " -A authtype Force use of authentication type NONE, PASSWORD, MD2, MD5 or OEM");
|
||||
lprintf(LOG_NOTICE, " -P password Remote session password");
|
||||
lprintf(LOG_NOTICE, " -a Prompt for remote password");
|
||||
lprintf(LOG_NOTICE, " -E Read password from IPMI_PASSWORD environment variable");
|
||||
lprintf(LOG_NOTICE, " -m address Set local IPMB address");
|
||||
lprintf(LOG_NOTICE, " -t address Bridge request to remote target address");
|
||||
lprintf(LOG_NOTICE, " -o oemtype Setup for OEM (use 'list' to see available OEM types)");
|
||||
#endif
|
||||
lprintf(LOG_NOTICE, "");
|
||||
ipmi_intf_print();
|
||||
ipmi_cmd_print();
|
||||
}
|
||||
|
||||
/* ipmi_password_file_read - Open file and read password from it
|
||||
*
|
||||
* @filename: file name to read from
|
||||
*
|
||||
* returns pointer to allocated buffer containing password
|
||||
* (caller is expected to free when finished)
|
||||
* returns NULL on error
|
||||
*/
|
||||
static char *
|
||||
ipmi_password_file_read(char * filename)
|
||||
{
|
||||
FILE * fp;
|
||||
char * pass = NULL;
|
||||
int l;
|
||||
|
||||
pass = malloc(16);
|
||||
if (pass == NULL) {
|
||||
lprintf(LOG_ERR, "ipmitool: malloc failure");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fp = ipmi_open_file_read((const char *)filename);
|
||||
if (fp == NULL) {
|
||||
lprintf(LOG_ERR, "Unable to open password file %s",
|
||||
filename);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* read in id */
|
||||
if (fgets(pass, 16, fp) == NULL) {
|
||||
lprintf(LOG_ERR, "Unable to read password from file %s",
|
||||
filename);
|
||||
fclose(fp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* remove trailing whitespace */
|
||||
l = strcspn(pass, " \r\n\t");
|
||||
if (l > 0) {
|
||||
pass[l] = '\0';
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
return pass;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char ** argv)
|
||||
{
|
||||
struct ipmi_intf * intf = NULL;
|
||||
uint8_t privlvl = 0;
|
||||
uint8_t target_addr = 0;
|
||||
uint8_t my_addr = 0;
|
||||
int authtype = -1;
|
||||
char * tmp = NULL;
|
||||
char * hostname = NULL;
|
||||
char * username = NULL;
|
||||
char * password = NULL;
|
||||
char * intfname = NULL;
|
||||
char * progname = NULL;
|
||||
char * oemtype = NULL;
|
||||
int port = 0;
|
||||
int argflag, i;
|
||||
int rc = -1;
|
||||
int rc;
|
||||
|
||||
/* save program name */
|
||||
progname = strrchr(argv[0], '/');
|
||||
progname = ((progname == NULL) ? argv[0] : progname);
|
||||
rc = ipmi_main(argc, argv, ipmitool_cmd_list, NULL);
|
||||
|
||||
while ((argflag = getopt(argc, (char **)argv, OPTION_STRING)) != -1)
|
||||
{
|
||||
switch (argflag) {
|
||||
case 'I':
|
||||
intfname = strdup(optarg);
|
||||
if (intfname == NULL) {
|
||||
lprintf(LOG_ERR, "ipmitool: malloc failure");
|
||||
goto out_free;
|
||||
}
|
||||
break;
|
||||
case 'h':
|
||||
ipmitool_usage();
|
||||
goto out_free;
|
||||
break;
|
||||
case 'V':
|
||||
printf("%s version %s\n", progname, VERSION);
|
||||
goto out_free;
|
||||
break;
|
||||
case 'p':
|
||||
port = atoi(optarg);
|
||||
break;
|
||||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
case 'c':
|
||||
csv_output = 1;
|
||||
break;
|
||||
case 'H':
|
||||
hostname = strdup(optarg);
|
||||
if (hostname == NULL) {
|
||||
lprintf(LOG_ERR, "ipmitool: malloc failure");
|
||||
goto out_free;
|
||||
}
|
||||
break;
|
||||
case 'f':
|
||||
if (password)
|
||||
free(password);
|
||||
password = ipmi_password_file_read(optarg);
|
||||
if (password == NULL)
|
||||
lprintf(LOG_ERR, "Unable to read password "
|
||||
"from file %s", optarg);
|
||||
break;
|
||||
case 'a':
|
||||
#ifdef HAVE_GETPASSPHRASE
|
||||
tmp = getpassphrase("Password: ");
|
||||
#else
|
||||
tmp = getpass("Password: ");
|
||||
#endif
|
||||
if (tmp != NULL) {
|
||||
if (password)
|
||||
free(password);
|
||||
password = strdup(tmp);
|
||||
if (password == NULL) {
|
||||
lprintf(LOG_ERR, "ipmitool: malloc failure");
|
||||
goto out_free;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'U':
|
||||
username = strdup(optarg);
|
||||
if (username == NULL) {
|
||||
lprintf(LOG_ERR, "ipmitool: malloc failure");
|
||||
goto out_free;
|
||||
}
|
||||
break;
|
||||
#ifndef __sun /* some options not enabled on solaris yet */
|
||||
case 'o':
|
||||
oemtype = strdup(optarg);
|
||||
if (oemtype == NULL) {
|
||||
lprintf(LOG_ERR, "ipmitool: malloc failure");
|
||||
goto out_free;
|
||||
}
|
||||
if (strncmp(oemtype, "list", 4) == 0) {
|
||||
ipmi_oem_print();
|
||||
goto out_free;
|
||||
}
|
||||
break;
|
||||
case 'g':
|
||||
/* backwards compatible oem hack */
|
||||
oemtype = strdup("intelwv2");
|
||||
break;
|
||||
case 's':
|
||||
/* backwards compatible oem hack */
|
||||
oemtype = strdup("supermicro");
|
||||
break;
|
||||
case 'P':
|
||||
if (password)
|
||||
free(password);
|
||||
password = strdup(optarg);
|
||||
if (password == NULL) {
|
||||
lprintf(LOG_ERR, "ipmitool: malloc failure");
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
/* Prevent password snooping with ps */
|
||||
i = strlen(optarg);
|
||||
memset(optarg, 'X', i);
|
||||
break;
|
||||
case 'E':
|
||||
if ((tmp = getenv("IPMITOOL_PASSWORD")))
|
||||
{
|
||||
if (password)
|
||||
free(password);
|
||||
password = strdup(tmp);
|
||||
if (password == NULL) {
|
||||
lprintf(LOG_ERR, "ipmitool: malloc failure");
|
||||
goto out_free;
|
||||
}
|
||||
}
|
||||
else if ((tmp = getenv("IPMI_PASSWORD")))
|
||||
{
|
||||
if (password)
|
||||
free(password);
|
||||
password = strdup(tmp);
|
||||
if (password == NULL) {
|
||||
lprintf(LOG_ERR, "ipmitool: malloc failure");
|
||||
goto out_free;
|
||||
}
|
||||
}
|
||||
else {
|
||||
lprintf(LOG_WARN, "Unable to read password from environment");
|
||||
}
|
||||
break;
|
||||
case 'L':
|
||||
privlvl = (uint8_t)str2val(optarg, ipmi_privlvl_vals);
|
||||
if (!privlvl)
|
||||
lprintf(LOG_WARN, "Invalid privilege level %s", optarg);
|
||||
break;
|
||||
case 'A':
|
||||
authtype = (int)str2val(optarg, ipmi_authtype_session_vals);
|
||||
break;
|
||||
case 't':
|
||||
target_addr = (uint8_t)strtol(optarg, NULL, 0);
|
||||
break;
|
||||
case 'm':
|
||||
my_addr = (uint8_t)strtol(optarg, NULL, 0);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
ipmitool_usage();
|
||||
goto out_free;
|
||||
}
|
||||
}
|
||||
|
||||
/* check for command before doing anything */
|
||||
if (argc-optind <= 0) {
|
||||
lprintf(LOG_ERR, "No command provided!");
|
||||
ipmitool_usage();
|
||||
goto out_free;
|
||||
}
|
||||
if (strncmp(argv[optind], "help", 4) == 0) {
|
||||
ipmi_cmd_print();
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the user has specified a hostname (-H option)
|
||||
* then this is a remote access session.
|
||||
*
|
||||
* If no password was specified by any other method
|
||||
* and the authtype was not explicitly set to NONE
|
||||
* then prompt the user.
|
||||
*/
|
||||
if (hostname != NULL && password == NULL &&
|
||||
(authtype != IPMI_SESSION_AUTHTYPE_NONE || authtype < 0)) {
|
||||
#ifdef HAVE_GETPASSPHRASE
|
||||
tmp = getpassphrase("Password: ");
|
||||
#else
|
||||
tmp = getpass("Password: ");
|
||||
#endif
|
||||
if (tmp != NULL) {
|
||||
password = strdup(tmp);
|
||||
if (password == NULL) {
|
||||
lprintf(LOG_ERR, "ipmitool: malloc failure");
|
||||
goto out_free;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* if no interface was specified but a
|
||||
* hostname was then use LAN by default
|
||||
* otherwise the default is hardcoded
|
||||
* to use the first entry in the list
|
||||
*/
|
||||
if (intfname == NULL && hostname != NULL) {
|
||||
intfname = strdup("lan");
|
||||
if (intfname == NULL) {
|
||||
lprintf(LOG_ERR, "ipmitool: malloc failure");
|
||||
goto out_free;
|
||||
}
|
||||
}
|
||||
|
||||
/* load interface */
|
||||
intf = ipmi_intf_load(intfname);
|
||||
if (intf == NULL) {
|
||||
lprintf(LOG_ERR, "Error loading interface %s", intfname);
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
/* setup log */
|
||||
log_init(progname, 0, verbose);
|
||||
|
||||
/* run OEM setup if found */
|
||||
if (oemtype != NULL &&
|
||||
ipmi_oem_setup(intf, oemtype) < 0) {
|
||||
lprintf(LOG_ERR, "OEM setup for \"%s\" failed", oemtype);
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
/* set session variables */
|
||||
if (hostname != NULL)
|
||||
ipmi_intf_session_set_hostname(intf, hostname);
|
||||
if (username != NULL)
|
||||
ipmi_intf_session_set_username(intf, username);
|
||||
if (password != NULL)
|
||||
ipmi_intf_session_set_password(intf, password);
|
||||
if (port > 0)
|
||||
ipmi_intf_session_set_port(intf, port);
|
||||
if (authtype >= 0)
|
||||
ipmi_intf_session_set_authtype(intf, (uint8_t)authtype);
|
||||
if (privlvl > 0)
|
||||
ipmi_intf_session_set_privlvl(intf, privlvl);
|
||||
else
|
||||
ipmi_intf_session_set_privlvl(intf,
|
||||
IPMI_SESSION_PRIV_ADMIN); /* default */
|
||||
|
||||
/* setup IPMB local and target address if given */
|
||||
intf->my_addr = my_addr ? : IPMI_BMC_SLAVE_ADDR;
|
||||
if (target_addr > 0) {
|
||||
/* need to open the interface first */
|
||||
if (intf->open != NULL)
|
||||
intf->open(intf);
|
||||
intf->target_addr = target_addr;
|
||||
/* must be admin level to do this over lan */
|
||||
ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN);
|
||||
}
|
||||
|
||||
/* now we finally run the command */
|
||||
rc = ipmi_cmd_run(intf,
|
||||
argv[optind],
|
||||
argc-optind-1,
|
||||
&(argv[optind+1]));
|
||||
|
||||
/* clean repository caches */
|
||||
ipmi_cleanup(intf);
|
||||
|
||||
/* call interface close function if available */
|
||||
if (intf->opened > 0 && intf->close != NULL)
|
||||
intf->close(intf);
|
||||
|
||||
out_free:
|
||||
log_halt();
|
||||
|
||||
if (intfname != NULL)
|
||||
free(intfname);
|
||||
if (hostname != NULL)
|
||||
free(hostname);
|
||||
if (username != NULL)
|
||||
free(username);
|
||||
if (password != NULL)
|
||||
free(password);
|
||||
if (oemtype != NULL)
|
||||
free(oemtype);
|
||||
|
||||
if (rc >= 0)
|
||||
exit(EXIT_SUCCESS);
|
||||
else
|
||||
if (rc < 0)
|
||||
exit(EXIT_FAILURE);
|
||||
else
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
@ -48,6 +48,8 @@
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stropts.h>
|
||||
#include <stddef.h>
|
||||
#include <stropts.h>
|
||||
|
||||
#include <ipmitool/ipmi.h>
|
||||
#include <ipmitool/ipmi_intf.h>
|
||||
@ -56,8 +58,19 @@
|
||||
#include "bmc.h"
|
||||
|
||||
static int curr_seq;
|
||||
static int bmc_method(int fd, int *if_type);
|
||||
struct ipmi_rs *(*sendrecv_fn)(struct ipmi_intf *, struct ipmi_rq *) = NULL;
|
||||
extern int verbose;
|
||||
|
||||
static void dump_request(bmc_req_t *request);
|
||||
static void dump_response(bmc_rsp_t *response);
|
||||
static struct ipmi_rs *ipmi_bmc_send_cmd_ioctl(struct ipmi_intf *intf,
|
||||
struct ipmi_rq *req);
|
||||
static struct ipmi_rs *ipmi_bmc_send_cmd_putmsg(struct ipmi_intf *intf,
|
||||
struct ipmi_rq *req);
|
||||
|
||||
#define MESSAGE_BUFSIZE 1024
|
||||
|
||||
struct ipmi_intf ipmi_bmc_intf = {
|
||||
name: "bmc",
|
||||
desc: "IPMI v2.0 BMC interface",
|
||||
@ -78,6 +91,8 @@ ipmi_bmc_close(struct ipmi_intf *intf)
|
||||
int
|
||||
ipmi_bmc_open(struct ipmi_intf *intf)
|
||||
{
|
||||
int method;
|
||||
|
||||
if (!intf)
|
||||
return -1;
|
||||
|
||||
@ -91,20 +106,36 @@ ipmi_bmc_open(struct ipmi_intf *intf)
|
||||
curr_seq = 0;
|
||||
|
||||
intf->opened = 1;
|
||||
|
||||
if (bmc_method(intf->fd, &method) < 0) {
|
||||
perror("Could not determine bmc messaging interface");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
sendrecv_fn = (method == BMC_PUTMSG_METHOD) ?
|
||||
ipmi_bmc_send_cmd_putmsg : ipmi_bmc_send_cmd_ioctl;
|
||||
|
||||
return (intf->fd);
|
||||
}
|
||||
|
||||
struct ipmi_rs *
|
||||
ipmi_bmc_send_cmd(struct ipmi_intf *intf, struct ipmi_rq *req)
|
||||
{
|
||||
struct strioctl istr;
|
||||
static struct bmc_reqrsp reqrsp;
|
||||
static struct ipmi_rs rsp;
|
||||
|
||||
/* If not already opened open the device or network connection */
|
||||
if (!intf->opened && intf->open && intf->open(intf) < 0)
|
||||
return NULL;
|
||||
|
||||
/* sendrecv_fn cannot be NULL at this point */
|
||||
return ((*sendrecv_fn)(intf, req));
|
||||
}
|
||||
|
||||
static struct ipmi_rs *
|
||||
ipmi_bmc_send_cmd_ioctl(struct ipmi_intf *intf, struct ipmi_rq *req)
|
||||
{
|
||||
struct strioctl istr;
|
||||
static struct bmc_reqrsp reqrsp;
|
||||
static struct ipmi_rs rsp;
|
||||
|
||||
memset(&reqrsp, 0, sizeof (reqrsp));
|
||||
reqrsp.req.fn = req->msg.netfn;
|
||||
reqrsp.req.lun = 0;
|
||||
@ -119,21 +150,200 @@ ipmi_bmc_send_cmd(struct ipmi_intf *intf, struct ipmi_rq *req)
|
||||
istr.ic_len = sizeof (struct bmc_reqrsp);
|
||||
|
||||
if (verbose) {
|
||||
printf("BMC req.fn : %x\n", reqrsp.req.fn);
|
||||
printf("BMC req.lun : %x\n", reqrsp.req.lun);
|
||||
printf("BMC req.cmd : %x\n", reqrsp.req.cmd);
|
||||
printf("BMC req.datalength : %d\n", reqrsp.req.datalength);
|
||||
printf("--\n");
|
||||
dump_request(&reqrsp.req);
|
||||
printf("--\n");
|
||||
}
|
||||
|
||||
if (ioctl(intf->fd, I_STR, &istr) < 0) {
|
||||
perror("BMC IOCTL: I_STR");
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (verbose > 2) {
|
||||
dump_response(&reqrsp.rsp);
|
||||
printf("--\n");
|
||||
}
|
||||
|
||||
memset(&rsp, 0, sizeof (struct ipmi_rs));
|
||||
rsp.ccode = reqrsp.rsp.ccode;
|
||||
rsp.data_len = reqrsp.rsp.datalength;
|
||||
|
||||
if (!rsp.ccode && rsp.data_len)
|
||||
/* Decrement for sizeof lun, cmd and ccode */
|
||||
rsp.data_len -= 3;
|
||||
|
||||
if (!rsp.ccode && (rsp.data_len > 0))
|
||||
memcpy(rsp.data, reqrsp.rsp.data, rsp.data_len);
|
||||
|
||||
return (&rsp);
|
||||
}
|
||||
|
||||
static struct ipmi_rs *
|
||||
ipmi_bmc_send_cmd_putmsg(struct ipmi_intf *intf, struct ipmi_rq *req)
|
||||
{
|
||||
struct strbuf sb;
|
||||
int flags = 0;
|
||||
static uint32_t msg_seq = 0;
|
||||
|
||||
/*
|
||||
* The length of the message structure is equal to the size of the
|
||||
* bmc_req_t structure, PLUS any additional data space in excess of
|
||||
* the data space already reserved in the data member + <n> for
|
||||
* the rest of the members in the bmc_msg_t structure.
|
||||
*/
|
||||
int msgsz = offsetof(bmc_msg_t, msg) + sizeof(bmc_req_t) +
|
||||
((req->msg.data_len > SEND_MAX_PAYLOAD_SIZE) ?
|
||||
(req->msg.data_len - SEND_MAX_PAYLOAD_SIZE) : 0);
|
||||
bmc_msg_t *msg = malloc(msgsz);
|
||||
bmc_req_t *request = (bmc_req_t *)&msg->msg[0];
|
||||
bmc_rsp_t *response;
|
||||
static struct ipmi_rs rsp;
|
||||
struct ipmi_rs *ret = NULL;
|
||||
|
||||
msg->m_type = BMC_MSG_REQUEST;
|
||||
msg->m_id = msg_seq++;
|
||||
request->fn = req->msg.netfn;
|
||||
request->lun = 0;
|
||||
request->cmd = req->msg.cmd;
|
||||
request->datalength = req->msg.data_len;
|
||||
memcpy(request->data, req->msg.data, req->msg.data_len);
|
||||
|
||||
sb.len = msgsz;
|
||||
sb.buf = (unsigned char *)msg;
|
||||
|
||||
if (verbose) {
|
||||
printf("--\n");
|
||||
dump_request(request);
|
||||
printf("--\n");
|
||||
}
|
||||
|
||||
if (putmsg(intf->fd, NULL, &sb, 0) < 0) {
|
||||
perror("BMC putmsg: ");
|
||||
free(msg);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
free(msg);
|
||||
|
||||
sb.buf = malloc(MESSAGE_BUFSIZE);
|
||||
sb.maxlen = MESSAGE_BUFSIZE;
|
||||
|
||||
if (getmsg(intf->fd, NULL, &sb, &flags) < 0) {
|
||||
perror("BMC getmsg: ");
|
||||
free(sb.buf);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
msg = (bmc_msg_t *)sb.buf;
|
||||
|
||||
if (verbose > 3) {
|
||||
printf("Got msg (id 0x%x) type 0x%x\n", msg->m_id, msg->m_type);
|
||||
}
|
||||
|
||||
|
||||
/* Did we get an error back from the stream? */
|
||||
switch (msg->m_type) {
|
||||
|
||||
case BMC_MSG_RESPONSE:
|
||||
response = (bmc_rsp_t *)&msg->msg[0];
|
||||
|
||||
if (verbose > 2) {
|
||||
dump_response(response);
|
||||
printf("--\n");
|
||||
}
|
||||
|
||||
memset(&rsp, 0, sizeof (struct ipmi_rs));
|
||||
rsp.ccode = response->ccode;
|
||||
rsp.data_len = response->datalength;
|
||||
|
||||
if (!rsp.ccode && (rsp.data_len > 0))
|
||||
memcpy(rsp.data, response->data, rsp.data_len);
|
||||
|
||||
ret = &rsp;
|
||||
break;
|
||||
|
||||
case BMC_MSG_ERROR:
|
||||
/* In case of an error, msg->msg[0] has the error code */
|
||||
printf("bmc_send_cmd: %s\n", strerror(msg->msg[0]));
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
free(sb.buf);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine which interface to use. Returns the interface method
|
||||
* to use.
|
||||
*/
|
||||
static int
|
||||
bmc_method(int fd, int *if_type)
|
||||
{
|
||||
struct strioctl istr;
|
||||
int retval = 0;
|
||||
uint8_t method = BMC_PUTMSG_METHOD;
|
||||
|
||||
istr.ic_cmd = IOCTL_IPMI_INTERFACE_METHOD;
|
||||
istr.ic_timout = 0;
|
||||
istr.ic_dp = (uint8_t *)&method;
|
||||
istr.ic_len = 1;
|
||||
|
||||
/*
|
||||
* If the ioctl doesn't exist, we should get an EINVAL back.
|
||||
* Bail out on any other error.
|
||||
*/
|
||||
if (ioctl(fd, I_STR, &istr) < 0) {
|
||||
|
||||
if (errno != EINVAL)
|
||||
retval = -1;
|
||||
else
|
||||
method = BMC_IOCTL_METHOD;
|
||||
}
|
||||
|
||||
if (retval == 0)
|
||||
*if_type = method;
|
||||
|
||||
return (retval);
|
||||
}
|
||||
|
||||
static void
|
||||
dump_request(bmc_req_t *request)
|
||||
{
|
||||
int i;
|
||||
|
||||
printf("BMC req.fn : 0x%x\n", request->fn);
|
||||
printf("BMC req.lun : 0x%x\n", request->lun);
|
||||
printf("BMC req.cmd : 0x%x\n", request->cmd);
|
||||
printf("BMC req.datalength : 0x%x\n", request->datalength);
|
||||
printf("BMC req.data : ");
|
||||
|
||||
if (request->datalength > 0) {
|
||||
for (i = 0; i < request->datalength; i++)
|
||||
printf("0x%x ", request->data[i]);
|
||||
} else {
|
||||
printf("<NONE>");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static void
|
||||
dump_response(bmc_rsp_t *response)
|
||||
{
|
||||
int i;
|
||||
|
||||
printf("BMC rsp.fn : 0x%x\n", response->fn);
|
||||
printf("BMC rsp.lun : 0x%x\n", response->lun);
|
||||
printf("BMC rsp.cmd : 0x%x\n", response->cmd);
|
||||
printf("BMC rsp.ccode : 0x%x\n", response->ccode);
|
||||
printf("BMC rsp.datalength : 0x%x\n", response->datalength);
|
||||
printf("BMC rsp.data : ");
|
||||
|
||||
if (response->datalength > 0) {
|
||||
for (i = 0; i < response->datalength; i++)
|
||||
printf("0x%x ", response->data[i]);
|
||||
} else {
|
||||
printf("<NONE>");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
@ -34,10 +34,10 @@
|
||||
* facility.
|
||||
*/
|
||||
|
||||
#ifndef _BMC_INTF_H_
|
||||
#define _BMC_INTF_H_
|
||||
#ifndef _BMC_INTF_H
|
||||
#define _BMC_INTF_H
|
||||
|
||||
#pragma ident "@(#)bmc_intf.h 1.2 04/08/25 SMI"
|
||||
#pragma ident "@(#)bmc_intf.h 1.2 05/03/07 SMI"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -46,13 +46,6 @@ extern "C" {
|
||||
#define BMC_SUCCESS 0x0
|
||||
#define BMC_FAILURE 0x1
|
||||
|
||||
#define IPMI_SUCCESS BMC_SUCCESS
|
||||
#define IPMI_FAILURE BMC_FAILURE
|
||||
|
||||
/* allau clean up */
|
||||
#define IPMI_FALSE 0
|
||||
#define IPMI_TRUE 1
|
||||
|
||||
#define BMC_NETFN_CHASSIS 0x0
|
||||
#define BMC_NETFN_BRIDGE 0x2
|
||||
#define BMC_NETFN_SE 0x4
|
||||
@ -95,27 +88,38 @@ extern "C" {
|
||||
|
||||
|
||||
#define IOCTL_IPMI_KCS_ACTION 0x01
|
||||
#define IOCTL_IPMI_INTERFACE_METHOD 0x02
|
||||
|
||||
/* Interface methods returned from IOCTL_IPMI_INTERFACE_METHOD ioctl: */
|
||||
|
||||
#define BMC_IOCTL_METHOD 0 /* Not returned from ioctl, */
|
||||
/* but can be used by */
|
||||
/* applications that want to */
|
||||
/* compare against an */
|
||||
/* alternative method. */
|
||||
#define BMC_PUTMSG_METHOD 1
|
||||
|
||||
/*
|
||||
* bmc_req_t is the data structure to send
|
||||
* request packet from applications to the driver
|
||||
* module.
|
||||
*
|
||||
* the request pkt is mainly for KCS-interface-BMC
|
||||
* messages. Since the system interface is session-less
|
||||
* connections, the packet won't have any session
|
||||
* information.
|
||||
*
|
||||
* the data payload will be 2 bytes less than max
|
||||
* BMC supported packet size.
|
||||
* the address of the responder is always BMC and so
|
||||
* rsSa field is not required.
|
||||
*/
|
||||
typedef struct bmc_req {
|
||||
unsigned char fn; /* netFn for command */
|
||||
unsigned char lun; /* logical unit on responder */
|
||||
unsigned char cmd; /* command */
|
||||
unsigned char datalength; /* length of following data */
|
||||
unsigned char data[SEND_MAX_PAYLOAD_SIZE]; /* request data */
|
||||
uint8_t fn; /* netFn for command */
|
||||
uint8_t lun; /* logical unit on responder */
|
||||
uint8_t cmd; /* command */
|
||||
uint8_t datalength; /* length of following data */
|
||||
uint8_t data[SEND_MAX_PAYLOAD_SIZE]; /* request data */
|
||||
} bmc_req_t;
|
||||
|
||||
/*
|
||||
@ -127,20 +131,21 @@ typedef struct bmc_req {
|
||||
* messages. Since the system interface is session-less
|
||||
* connections, the packet won't have any session
|
||||
* information.
|
||||
*
|
||||
* the data payload will be 2 bytes less than max
|
||||
* BMC supported packet size.
|
||||
*/
|
||||
typedef struct bmc_rsp {
|
||||
unsigned char fn; /* netFn for command */
|
||||
unsigned char lun; /* logical unit on responder */
|
||||
unsigned char cmd; /* command */
|
||||
unsigned char ccode; /* completion code */
|
||||
unsigned char datalength; /* Length */
|
||||
unsigned char data[RECV_MAX_PAYLOAD_SIZE]; /* response */
|
||||
uint8_t fn; /* netFn for command */
|
||||
uint8_t lun; /* logical unit on responder */
|
||||
uint8_t cmd; /* command */
|
||||
uint8_t ccode; /* completion code */
|
||||
uint8_t datalength; /* Length */
|
||||
uint8_t data[RECV_MAX_PAYLOAD_SIZE]; /* response */
|
||||
} bmc_rsp_t;
|
||||
|
||||
/*
|
||||
* the data structure for synchronous operation.
|
||||
* the data structure for synchronous operation via ioctl (DEPRECATED)
|
||||
*/
|
||||
typedef struct bmc_reqrsp {
|
||||
bmc_req_t req; /* request half */
|
||||
@ -148,38 +153,59 @@ typedef struct bmc_reqrsp {
|
||||
} bmc_reqrsp_t;
|
||||
|
||||
|
||||
#ifdef _KERNEL
|
||||
/*
|
||||
* The new way of communicating with the bmc driver is to use putmsg() to
|
||||
* send a message of a particular type. Replies from the driver also have this
|
||||
* form, and will require the user to process the type field before examining
|
||||
* the rest of the reply.
|
||||
*
|
||||
* The only change that must be observed when using the request and response
|
||||
* structures defined above is as follows:
|
||||
* when sending messages to the bmc driver, the data portion is now variable
|
||||
* (the caller must allocate enough space to store the all structure members,
|
||||
* plus enough space to cover the amount of data in the request), e.g.:
|
||||
*
|
||||
* bmc_msg_t *msg = malloc(offsetof(bmc_msg_t, msg) + sizeof(bmc_req_t) + 10);
|
||||
*
|
||||
* The amount allocated for the message is (# of bytes before the msg field) +
|
||||
* the size of a bmc_req_t (which includes SEND_MAX_PAYLOAD_SIZE
|
||||
* bytes in the data field), plus an additional 10 bytes for the data
|
||||
* field (so the data field would occupy (SEND_MAX_PAYLOAD_SIZE + 10)
|
||||
* bytes). The datalength member must reflect the amount of data in the
|
||||
* request's data field (as was required when using the ioctl interface).
|
||||
*/
|
||||
typedef struct bmc_msg {
|
||||
uint8_t m_type; /* Message type (see below) */
|
||||
uint32_t m_id; /* Message ID */
|
||||
uint8_t reserved[32];
|
||||
uint8_t msg[1]; /* Variable length message data */
|
||||
} bmc_msg_t;
|
||||
|
||||
|
||||
/*
|
||||
* data structure to send a message to BMC.
|
||||
* Ref. IPMI Spec 9.2
|
||||
* An error response passed back from the bmc driver will have its m_id
|
||||
* field set to BMC_UNKNOWN_MSG_ID if a message is sent to it that is not
|
||||
* at least as large as a bmc_msg_t.
|
||||
*/
|
||||
typedef struct bmc_send {
|
||||
unsigned char fnlun; /* Network Function and LUN */
|
||||
unsigned char cmd; /* command */
|
||||
unsigned char data[SEND_MAX_PAYLOAD_SIZE];
|
||||
} bmc_send_t;
|
||||
#define BMC_UNKNOWN_MSG_ID ~((uint32_t)0)
|
||||
|
||||
|
||||
/*
|
||||
* data structure to receive a message from BMC.
|
||||
* Ref. IPMI Spec 9.3
|
||||
* Possible values for the m_type field in bmc_msg_t:
|
||||
*/
|
||||
typedef struct bmc_recv {
|
||||
unsigned char fnlun; /* Network Function and LUN */
|
||||
unsigned char cmd; /* command */
|
||||
unsigned char ccode; /* completion code */
|
||||
unsigned char data[RECV_MAX_PAYLOAD_SIZE];
|
||||
} bmc_recv_t;
|
||||
|
||||
|
||||
#endif /* _KERNEL */
|
||||
#define BMC_MSG_REQUEST 1 /* BMC request (as above, sent to the */
|
||||
/* driver by the user), bmc_msg.msg */
|
||||
/* begins with the bmc_req_t */
|
||||
/* structure. */
|
||||
#define BMC_MSG_RESPONSE 2 /* BMC response (sent by the driver) */
|
||||
/* bmc_msg.msg begins with the */
|
||||
/* bmc_rsp_t structure. */
|
||||
#define BMC_MSG_ERROR 3 /* Error while processing a user msg */
|
||||
/* msg[0] is the error code */
|
||||
/* (interpret as an errno value) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _BMC_INTF_H_ */
|
||||
#endif /* _BMC_INTF_H */
|
||||
|
@ -89,14 +89,29 @@ struct ipmi_intf * ipmi_intf_table[] = {
|
||||
*
|
||||
* no meaningful return code
|
||||
*/
|
||||
void ipmi_intf_print(void)
|
||||
void ipmi_intf_print(struct ipmi_intf_support * intflist)
|
||||
{
|
||||
struct ipmi_intf ** intf;
|
||||
struct ipmi_intf_support * sup;
|
||||
int def = 1;
|
||||
int found;
|
||||
|
||||
lprintf(LOG_NOTICE, "Interfaces:");
|
||||
|
||||
for (intf = ipmi_intf_table; intf && *intf; intf++) {
|
||||
|
||||
if (intflist != NULL) {
|
||||
found = 0;
|
||||
for (sup=intflist; sup->name != NULL; sup++) {
|
||||
if (strncmp(sup->name, (*intf)->name, strlen(sup->name)) == 0 &&
|
||||
strncmp(sup->name, (*intf)->name, strlen((*intf)->name)) == 0 &&
|
||||
sup->supported == 1)
|
||||
found = 1;
|
||||
}
|
||||
if (found == 0)
|
||||
continue;
|
||||
}
|
||||
|
||||
lprintf(LOG_NOTICE, "\t%-12s %s %s",
|
||||
(*intf)->name, (*intf)->desc,
|
||||
def ? "[default]" : "");
|
||||
@ -165,7 +180,7 @@ ipmi_intf_session_set_username(struct ipmi_intf * intf, char * username)
|
||||
if (intf->session == NULL)
|
||||
return;
|
||||
|
||||
memset(intf->session->username, 0, 16);
|
||||
memset(intf->session->username, 0, 17);
|
||||
|
||||
if (username == NULL)
|
||||
return;
|
||||
@ -200,6 +215,39 @@ ipmi_intf_session_set_privlvl(struct ipmi_intf * intf, uint8_t level)
|
||||
intf->session->privlvl = level;
|
||||
}
|
||||
|
||||
void
|
||||
ipmi_intf_session_set_cipher_suite_id(struct ipmi_intf * intf, uint8_t cipher_suite_id)
|
||||
{
|
||||
if (intf->session == NULL)
|
||||
return;
|
||||
|
||||
intf->session->cipher_suite_id = cipher_suite_id;
|
||||
}
|
||||
|
||||
void
|
||||
ipmi_intf_session_set_sol_escape_char(struct ipmi_intf * intf, char sol_escape_char)
|
||||
{
|
||||
if (intf->session == NULL)
|
||||
return;
|
||||
|
||||
intf->session->sol_escape_char = sol_escape_char;
|
||||
}
|
||||
|
||||
void
|
||||
ipmi_intf_session_set_kgkey(struct ipmi_intf * intf, char * kgkey)
|
||||
{
|
||||
if (intf->session == NULL)
|
||||
return;
|
||||
|
||||
memset(intf->session->v2_data.kg, 0, IPMI_KG_BUFFER_SIZE);
|
||||
|
||||
if (kgkey == NULL)
|
||||
return;
|
||||
|
||||
memcpy(intf->session->v2_data.kg, kgkey,
|
||||
__min(strlen(kgkey), IPMI_KG_BUFFER_SIZE));
|
||||
}
|
||||
|
||||
void
|
||||
ipmi_intf_session_set_port(struct ipmi_intf * intf, int port)
|
||||
{
|
||||
@ -218,6 +266,24 @@ ipmi_intf_session_set_authtype(struct ipmi_intf * intf, uint8_t authtype)
|
||||
intf->session->authtype_set = authtype;
|
||||
}
|
||||
|
||||
void
|
||||
ipmi_intf_session_set_timeout(struct ipmi_intf * intf, uint32_t timeout)
|
||||
{
|
||||
if (intf->session == NULL)
|
||||
return;
|
||||
|
||||
intf->session->timeout = timeout;
|
||||
}
|
||||
|
||||
void
|
||||
ipmi_intf_session_set_retry(struct ipmi_intf * intf, int retry)
|
||||
{
|
||||
if (intf->session == NULL)
|
||||
return;
|
||||
|
||||
intf->session->retry = retry;
|
||||
}
|
||||
|
||||
void
|
||||
ipmi_cleanup(struct ipmi_intf * intf)
|
||||
{
|
||||
|
@ -75,6 +75,8 @@ static struct ipmi_rq_entry * ipmi_req_entries_tail;
|
||||
|
||||
extern int verbose;
|
||||
|
||||
static uint8_t bridgePossible = 0;
|
||||
|
||||
static sigjmp_buf jmpbuf;
|
||||
|
||||
static int ipmi_lan_send_packet(struct ipmi_intf * intf, uint8_t * data, int data_len);
|
||||
@ -101,40 +103,6 @@ query_alarm(int signo)
|
||||
siglongjmp(jmpbuf, 1);
|
||||
}
|
||||
|
||||
static const struct valstr ipmi_channel_protocol_vals[] = {
|
||||
{ 0x00, "reserved" },
|
||||
{ 0x01, "IPMB-1.0" },
|
||||
{ 0x02, "ICMB-1.0" },
|
||||
{ 0x03, "reserved" },
|
||||
{ 0x04, "IPMI-SMBus" },
|
||||
{ 0x05, "KCS" },
|
||||
{ 0x06, "SMIC" },
|
||||
{ 0x07, "BT-10" },
|
||||
{ 0x08, "BT-15" },
|
||||
{ 0x09, "TMode" },
|
||||
{ 0x1c, "OEM 1" },
|
||||
{ 0x1d, "OEM 2" },
|
||||
{ 0x1e, "OEM 3" },
|
||||
{ 0x1f, "OEM 4" },
|
||||
{ 0x00, NULL },
|
||||
};
|
||||
|
||||
static const struct valstr ipmi_channel_medium_vals[] = {
|
||||
{ 0x00, "reserved" },
|
||||
{ 0x01, "IPMB (I2C)" },
|
||||
{ 0x02, "ICMB v1.0" },
|
||||
{ 0x03, "ICMB v0.9" },
|
||||
{ 0x04, "802.3 LAN" },
|
||||
{ 0x05, "Serial/Modem" },
|
||||
{ 0x06, "Other LAN" },
|
||||
{ 0x07, "PCI SMBus" },
|
||||
{ 0x08, "SMBus v1.0/v1.1" },
|
||||
{ 0x09, "SMBus v2.0" },
|
||||
{ 0x0a, "USB 1.x" },
|
||||
{ 0x0b, "USB 2.x" },
|
||||
{ 0x0c, "System Interface" },
|
||||
{ 0x00, NULL },
|
||||
};
|
||||
|
||||
static struct ipmi_rq_entry *
|
||||
ipmi_req_add_entry(struct ipmi_intf * intf, struct ipmi_rq * req)
|
||||
@ -168,7 +136,7 @@ ipmi_req_lookup_entry(uint8_t seq, uint8_t cmd)
|
||||
{
|
||||
struct ipmi_rq_entry * e = ipmi_req_entries;
|
||||
while (e && (e->rq_seq != seq || e->req.msg.cmd != cmd)) {
|
||||
if (e == e->next)
|
||||
if (e->next == NULL || e == e->next)
|
||||
return NULL;
|
||||
e = e->next;
|
||||
}
|
||||
@ -217,10 +185,16 @@ ipmi_req_clear_entries(void)
|
||||
while (e) {
|
||||
lprintf(LOG_DEBUG+3, "cleared list entry seq=0x%02x cmd=0x%02x",
|
||||
e->rq_seq, e->req.msg.cmd);
|
||||
if (e->next != NULL) {
|
||||
p = e->next;
|
||||
free(e);
|
||||
e = p;
|
||||
} else {
|
||||
free(e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
ipmi_req_entries = NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -257,7 +231,7 @@ struct ipmi_rs * ipmi_lan_recv_packet(struct ipmi_intf * intf)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
alarm(IPMI_LAN_TIMEOUT);
|
||||
alarm(intf->session->timeout);
|
||||
rc = recv(intf->fd, &rsp.data, IPMI_BUF_SIZE, 0);
|
||||
alarm(0);
|
||||
|
||||
@ -272,7 +246,7 @@ struct ipmi_rs * ipmi_lan_recv_packet(struct ipmi_intf * intf)
|
||||
* response is read before the connection refused is returned)
|
||||
*/
|
||||
if (rc < 0) {
|
||||
alarm(IPMI_LAN_TIMEOUT);
|
||||
alarm(intf->session->timeout);
|
||||
rc = recv(intf->fd, &rsp.data, IPMI_BUF_SIZE, 0);
|
||||
alarm(0);
|
||||
if (rc < 0) {
|
||||
@ -329,7 +303,7 @@ ipmi_handle_pong(struct ipmi_intf * intf, struct ipmi_rs * rsp)
|
||||
" ASF Version %s\n"
|
||||
" RMCP Version %s\n"
|
||||
" RMCP Sequence %d\n"
|
||||
" IANA Enterprise %d\n",
|
||||
" IANA Enterprise %ld\n",
|
||||
(pong->sup_entities & 0x80) ? "" : " NOT",
|
||||
(pong->sup_entities & 0x01) ? "1.0" : "unknown",
|
||||
(pong->rmcp.ver == 6) ? "1.0" : "unknown",
|
||||
@ -362,7 +336,7 @@ int
|
||||
ipmi_lan_ping(struct ipmi_intf * intf)
|
||||
{
|
||||
struct asf_hdr asf_ping = {
|
||||
.iana = ASF_RMCP_IANA,
|
||||
.iana = htonl(ASF_RMCP_IANA),
|
||||
.type = ASF_TYPE_PING,
|
||||
};
|
||||
struct rmcp_hdr rmcp_ping = {
|
||||
@ -426,6 +400,14 @@ 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;
|
||||
|
||||
if(ourAddress == 0)
|
||||
{
|
||||
ourAddress = IPMI_BMC_SLAVE_ADDR;
|
||||
}
|
||||
|
||||
|
||||
|
||||
rsp = ipmi_lan_recv_packet(intf);
|
||||
|
||||
@ -504,16 +486,29 @@ 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 != IPMI_BMC_SLAVE_ADDR) {
|
||||
if (rsp->data_len)
|
||||
lprintf(LOG_DEBUG+1, "Bridged cmd %02x resp: %s",
|
||||
rsp->payload.ipmi_response.cmd,
|
||||
buf2str(&rsp->data[x],rsp->data_len));
|
||||
if (
|
||||
(intf->target_addr != ourAddress) &&
|
||||
(bridgePossible)
|
||||
)
|
||||
{
|
||||
if(
|
||||
(rsp->data_len) &&
|
||||
(rsp->payload.ipmi_response.cmd != 0x34)
|
||||
)
|
||||
{
|
||||
printbuf(
|
||||
&rsp->data[x],
|
||||
(rsp->data_len-x),
|
||||
"bridge command response");
|
||||
}
|
||||
/* bridged command: lose extra header */
|
||||
if (rsp->payload.ipmi_response.cmd == 0x34) {
|
||||
if( rsp->data_len == 38 )
|
||||
{
|
||||
entry->req.msg.cmd = entry->req.msg.target_cmd;
|
||||
rsp = ipmi_lan_recv_packet(intf);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
//x += sizeof(rsp->payload.ipmi_response);
|
||||
if (rsp->data[x-1] != 0)
|
||||
@ -587,6 +582,13 @@ 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;
|
||||
|
||||
if(ourAddress == 0)
|
||||
{
|
||||
ourAddress = IPMI_BMC_SLAVE_ADDR;
|
||||
}
|
||||
|
||||
if (curr_seq >= 64)
|
||||
curr_seq = 0;
|
||||
@ -627,15 +629,22 @@ ipmi_lan_build_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
|
||||
}
|
||||
|
||||
/* message length */
|
||||
if (intf->target_addr == IPMI_BMC_SLAVE_ADDR) {
|
||||
if (
|
||||
(intf->target_addr == ourAddress) ||
|
||||
(!bridgePossible)
|
||||
)
|
||||
{
|
||||
msg[len++] = req->msg.data_len + 7;
|
||||
cs = mp = len;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
/* bridged request: encapsulate w/in Send Message */
|
||||
bridgedRequest = 1;
|
||||
msg[len++] = req->msg.data_len + 15;
|
||||
cs = mp = len;
|
||||
msg[len++] = IPMI_BMC_SLAVE_ADDR;
|
||||
|
||||
msg[len++] = IPMI_NETFN_APP << 2;
|
||||
tmp = len - cs;
|
||||
msg[len++] = ipmi_csum(msg+cs, tmp);
|
||||
@ -645,7 +654,7 @@ ipmi_lan_build_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
|
||||
msg[len++] = 0x34; /* Send Message rqst */
|
||||
entry->req.msg.target_cmd = entry->req.msg.cmd; /* Save target command */
|
||||
entry->req.msg.cmd = 0x34; /* (fixup request entry) */
|
||||
msg[len++] = 0x40; /* Track request, Channel=IPMB */
|
||||
msg[len++] = (0x40|intf->target_channel); /* Track request*/
|
||||
cs = len;
|
||||
}
|
||||
|
||||
@ -655,8 +664,11 @@ ipmi_lan_build_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
|
||||
tmp = len - cs;
|
||||
msg[len++] = ipmi_csum(msg+cs, tmp);
|
||||
cs = len;
|
||||
if (!bridgedRequest)
|
||||
msg[len++] = IPMI_REMOTE_SWID;
|
||||
|
||||
else /* Bridged message */
|
||||
msg[len++] = intf->my_addr;
|
||||
entry->rq_seq = curr_seq++;
|
||||
msg[len++] = entry->rq_seq << 2;
|
||||
msg[len++] = req->msg.cmd;
|
||||
@ -686,11 +698,13 @@ ipmi_lan_build_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
|
||||
msg[len++] = ipmi_csum(msg+cs, tmp);
|
||||
|
||||
/* bridged request: 2nd checksum */
|
||||
if (intf->target_addr != IPMI_BMC_SLAVE_ADDR) {
|
||||
if (bridgedRequest)
|
||||
{
|
||||
tmp = len - cs2;
|
||||
msg[len++] = ipmi_csum(msg+cs2, tmp);
|
||||
}
|
||||
|
||||
|
||||
if (s->active) {
|
||||
/*
|
||||
* s->authcode is already copied to msg+ap but some
|
||||
@ -725,7 +739,7 @@ struct ipmi_rs *
|
||||
ipmi_lan_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
|
||||
{
|
||||
struct ipmi_rq_entry * entry;
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rs * rsp = NULL;
|
||||
int try = 0;
|
||||
|
||||
if (intf->opened == 0 && intf->open != NULL) {
|
||||
@ -746,6 +760,10 @@ ipmi_lan_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* if we are set to noanswer we do not expect response */
|
||||
if (intf->noanswer)
|
||||
break;
|
||||
|
||||
if (ipmi_oem_active(intf, "intelwv2"))
|
||||
ipmi_lan_thump(intf);
|
||||
|
||||
@ -756,7 +774,7 @@ ipmi_lan_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
|
||||
break;
|
||||
|
||||
usleep(5000);
|
||||
if (++try >= IPMI_LAN_RETRY) {
|
||||
if (++try >= intf->session->retry) {
|
||||
lprintf(LOG_DEBUG, " No response from remote controller");
|
||||
break;
|
||||
}
|
||||
@ -1127,7 +1145,7 @@ ipmi_activate_session_cmd(struct ipmi_intf * intf)
|
||||
printbuf(rsp->data, rsp->data_len, "activate_session");
|
||||
|
||||
if (rsp->ccode) {
|
||||
lprintf(LOG_ERR, "Activate Session error:");
|
||||
fprintf(stderr, "Activate Session error:");
|
||||
switch (rsp->ccode) {
|
||||
case 0x81:
|
||||
lprintf(LOG_ERR, "\tNo session slot available");
|
||||
@ -1173,6 +1191,8 @@ ipmi_activate_session_cmd(struct ipmi_intf * intf)
|
||||
return -1;
|
||||
}
|
||||
|
||||
bridgePossible = 1;
|
||||
|
||||
lprintf(LOG_DEBUG, "\nSession Activated");
|
||||
lprintf(LOG_DEBUG, " Auth Type : %s",
|
||||
val2str(rsp->data[0], ipmi_authtype_session_vals));
|
||||
@ -1194,6 +1214,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;
|
||||
|
||||
if (privlvl <= IPMI_SESSION_PRIV_USER)
|
||||
return 0; /* no need to set higher */
|
||||
@ -1204,7 +1225,12 @@ ipmi_set_session_privlvl_cmd(struct ipmi_intf * intf)
|
||||
req.msg.data = &privlvl;
|
||||
req.msg.data_len = 1;
|
||||
|
||||
bridgePossible = 0;
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
|
||||
bridgePossible = backupBridgePossible;
|
||||
|
||||
if (rsp == NULL) {
|
||||
lprintf(LOG_ERR, "Set Session Privilege Level to %s failed",
|
||||
val2str(privlvl, ipmi_privlvl_vals));
|
||||
@ -1215,7 +1241,8 @@ ipmi_set_session_privlvl_cmd(struct ipmi_intf * intf)
|
||||
|
||||
if (rsp->ccode > 0) {
|
||||
lprintf(LOG_ERR, "Set Session Privilege Level to %s failed: %s",
|
||||
val2str(privlvl, ipmi_privlvl_vals));
|
||||
val2str(privlvl, ipmi_privlvl_vals),
|
||||
val2str(rsp->ccode, completion_code_vals));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1237,6 +1264,7 @@ ipmi_close_session_cmd(struct ipmi_intf * intf)
|
||||
return -1;
|
||||
|
||||
intf->target_addr = IPMI_BMC_SLAVE_ADDR;
|
||||
bridgePossible = 0; /* Not a bridge message */
|
||||
|
||||
memcpy(&msg_data, &session_id, 4);
|
||||
|
||||
@ -1295,7 +1323,7 @@ ipmi_lan_activate_session(struct ipmi_intf * intf)
|
||||
/* don't fail on ping because its not always supported.
|
||||
* Supermicro's IPMI LAN 1.5 cards don't tolerate pings.
|
||||
*/
|
||||
if (ipmi_oem_active(intf, "supermicro"))
|
||||
if (!ipmi_oem_active(intf, "supermicro"))
|
||||
ipmi_lan_ping(intf);
|
||||
|
||||
/* Some particular Intel boards need special help
|
||||
@ -1319,12 +1347,12 @@ ipmi_lan_activate_session(struct ipmi_intf * intf)
|
||||
if (rc < 0)
|
||||
goto fail;
|
||||
|
||||
intf->abort = 0;
|
||||
|
||||
rc = ipmi_set_session_privlvl_cmd(intf);
|
||||
if (rc < 0)
|
||||
goto fail;
|
||||
|
||||
intf->abort = 0;
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
@ -1365,6 +1393,10 @@ int ipmi_lan_open(struct ipmi_intf * intf)
|
||||
s->port = IPMI_LAN_PORT;
|
||||
if (s->privlvl == 0)
|
||||
s->privlvl = IPMI_SESSION_PRIV_ADMIN;
|
||||
if (s->timeout == 0)
|
||||
s->timeout = IPMI_LAN_TIMEOUT;
|
||||
if (s->retry == 0)
|
||||
s->retry = IPMI_LAN_RETRY;
|
||||
|
||||
if (s->hostname == NULL || strlen(s->hostname) == 0) {
|
||||
lprintf(LOG_ERR, "No hostname specified!");
|
||||
@ -1378,7 +1410,11 @@ int ipmi_lan_open(struct ipmi_intf * intf)
|
||||
s->addr.sin_family = AF_INET;
|
||||
s->addr.sin_port = htons(s->port);
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
rc = inet_aton(s->hostname, &s->addr.sin_addr);
|
||||
#else
|
||||
rc = inet_pton(AF_INET, s->hostname, &s->addr.sin_addr);
|
||||
#endif
|
||||
if (rc <= 0) {
|
||||
struct hostent *host = gethostbyname(s->hostname);
|
||||
if (host == NULL) {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -80,23 +80,6 @@
|
||||
#define IPMI_PRIV_OEM 5
|
||||
|
||||
|
||||
/* From table 13-17 of the IPMI v2 specification */
|
||||
#define IPMI_AUTH_RAKP_NONE 0x00
|
||||
#define IPMI_AUTH_RAKP_HMAC_SHA1 0x01
|
||||
#define IPMI_AUTH_RAKP_HMAC_MD5 0x02
|
||||
|
||||
/* From table 13-18 of the IPMI v2 specification */
|
||||
#define IPMI_INTEGRITY_NONE 0x00
|
||||
#define IPMI_INTEGRITY_HMAC_SHA1_96 0x01
|
||||
#define IPMI_INTEGRITY_HMAC_MD5_128 0x02
|
||||
#define IPMI_INTEGRITY_MD5_128 0x03
|
||||
|
||||
/* From table 13-19 of the IPMI v2 specfication */
|
||||
#define IPMI_CRYPT_NONE 0x00
|
||||
#define IPMI_CRYPT_AES_CBC_128 0x01
|
||||
#define IPMI_CRYPT_XRC4_128 0x02
|
||||
#define IPMI_CRYPT_XRC4_40 0x03
|
||||
|
||||
#define IPMI_CRYPT_AES_CBC_128_BLOCK_SIZE 0x10
|
||||
|
||||
|
||||
@ -115,7 +98,7 @@
|
||||
* TODO: these are wild guesses and should be checked
|
||||
*/
|
||||
#define IPMI_MAX_CONF_HEADER_SIZE 0x20
|
||||
#define IPMI_MAX_PAYLOAD_SIZE 0xFF /* Includes confidentiality header/trailer */
|
||||
#define IPMI_MAX_PAYLOAD_SIZE 0xFFFF /* Includes confidentiality header/trailer */
|
||||
#define IPMI_MAX_CONF_TRAILER_SIZE 0x20
|
||||
#define IPMI_MAX_INTEGRITY_PAD_SIZE 0x20
|
||||
#define IPMI_MAX_AUTH_CODE_SIZE 0x20
|
||||
@ -129,7 +112,7 @@
|
||||
* one integrity algorithm, and 1 encyrption alogrithm
|
||||
*/
|
||||
#define IPMI_OPEN_SESSION_REQUEST_SIZE 32
|
||||
#define IPMI_RAKP1_MESSAGE_SIZE 43
|
||||
#define IPMI_RAKP1_MESSAGE_SIZE 44
|
||||
#define IPMI_RAKP3_MESSAGE_MAX_SIZE 28
|
||||
|
||||
#define IPMI_MAX_USER_NAME_LENGTH 16
|
||||
|
@ -71,12 +71,13 @@
|
||||
* 1 on failure (the authcode does not match)
|
||||
*/
|
||||
int lanplus_rakp2_hmac_matches(const struct ipmi_session * session,
|
||||
const uint8_t * bmc_mac)
|
||||
const uint8_t * bmc_mac,
|
||||
struct ipmi_intf * intf)
|
||||
{
|
||||
char * buffer;
|
||||
int bufferLength, i;
|
||||
uint8_t mac[20];
|
||||
int macLength;
|
||||
uint32_t macLength;
|
||||
|
||||
uint32_t SIDm_lsbf, SIDc_lsbf;
|
||||
|
||||
@ -84,7 +85,7 @@ int lanplus_rakp2_hmac_matches(const struct ipmi_session * session,
|
||||
if (session->v2_data.auth_alg == IPMI_AUTH_RAKP_NONE)
|
||||
return 1;
|
||||
|
||||
/* We don't yet support other alogrithms */
|
||||
/* We don't yet support other algorithms */
|
||||
assert(session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_SHA1);
|
||||
|
||||
|
||||
@ -167,14 +168,12 @@ int lanplus_rakp2_hmac_matches(const struct ipmi_session * session,
|
||||
printbuf((char*)(session->authcode), IPMI_AUTHCODE_BUFFER_SIZE, ">> rakp2 mac key");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The buffer is complete. Let's hash.
|
||||
*/
|
||||
lanplus_HMAC(session->v2_data.auth_alg,
|
||||
session->authcode,
|
||||
(session->authcode[IPMI_AUTHCODE_BUFFER_SIZE] == 0?
|
||||
strlen(session->authcode): IPMI_AUTHCODE_BUFFER_SIZE),
|
||||
IPMI_AUTHCODE_BUFFER_SIZE,
|
||||
buffer,
|
||||
bufferLength,
|
||||
mac,
|
||||
@ -211,25 +210,36 @@ int lanplus_rakp2_hmac_matches(const struct ipmi_session * session,
|
||||
*
|
||||
* If the authentication algorithm is IPMI_AUTH_RAKP_NONE, we return success.
|
||||
*
|
||||
* return 0 on success (the authcode matches)
|
||||
* 1 on failure (the authcode does not match)
|
||||
* return 1 on success (the authcode matches)
|
||||
* 0 on failure (the authcode does not match)
|
||||
*
|
||||
*/
|
||||
int lanplus_rakp4_hmac_matches(const struct ipmi_session * session,
|
||||
const uint8_t * bmc_mac)
|
||||
const uint8_t * bmc_mac,
|
||||
struct ipmi_intf * intf)
|
||||
{
|
||||
char * buffer;
|
||||
int bufferLength, i;
|
||||
uint8_t mac[20];
|
||||
int macLength;
|
||||
uint32_t macLength;
|
||||
|
||||
uint32_t SIDc_lsbf;
|
||||
|
||||
if (ipmi_oem_active(intf, "intelplus")){
|
||||
/* 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;
|
||||
|
||||
/* We don't yet support other alogrithms */
|
||||
assert(session->v2_data.auth_alg == IPMI_INTEGRITY_HMAC_SHA1_96);
|
||||
|
||||
/* We don't yet support other algorithms */
|
||||
assert(session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_SHA1);
|
||||
}
|
||||
|
||||
bufferLength =
|
||||
16 + /* Rm */
|
||||
@ -285,9 +295,11 @@ int lanplus_rakp4_hmac_matches(const struct ipmi_session * session,
|
||||
/*
|
||||
* The buffer is complete. Let's hash.
|
||||
*/
|
||||
lanplus_HMAC(session->v2_data.auth_alg,
|
||||
lanplus_HMAC((ipmi_oem_active(intf, "intelplus"))
|
||||
? session->v2_data.integrity_alg
|
||||
: session->v2_data.auth_alg ,
|
||||
session->v2_data.sik,
|
||||
20,
|
||||
IPMI_SIK_BUFFER_SIZE,
|
||||
buffer,
|
||||
bufferLength,
|
||||
mac,
|
||||
@ -295,6 +307,7 @@ int lanplus_rakp4_hmac_matches(const struct ipmi_session * session,
|
||||
|
||||
if (verbose > 2)
|
||||
{
|
||||
printbuf(bmc_mac, macLength, ">> rakp4 mac as computed by the BMC");
|
||||
printbuf(mac, macLength, ">> rakp4 mac as computed by the remote console");
|
||||
}
|
||||
|
||||
@ -332,7 +345,8 @@ int lanplus_rakp4_hmac_matches(const struct ipmi_session * session,
|
||||
*/
|
||||
int lanplus_generate_rakp3_authcode(char * output_buffer,
|
||||
const struct ipmi_session * session,
|
||||
uint32_t * mac_length)
|
||||
uint32_t * mac_length,
|
||||
struct ipmi_intf * intf)
|
||||
{
|
||||
int ret = 0;
|
||||
int input_buffer_length, i;
|
||||
@ -346,7 +360,7 @@ int lanplus_generate_rakp3_authcode(char * output_buffer,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* We don't yet support other alogrithms */
|
||||
/* We don't yet support other algorithms */
|
||||
assert(session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_SHA1);
|
||||
|
||||
input_buffer_length =
|
||||
@ -384,6 +398,9 @@ int lanplus_generate_rakp3_authcode(char * output_buffer,
|
||||
memcpy(input_buffer + 16, &SIDm_lsbf, 4);
|
||||
|
||||
/* ROLEm */
|
||||
if (ipmi_oem_active(intf, "intelplus"))
|
||||
input_buffer[20] = session->privlvl;
|
||||
else
|
||||
input_buffer[20] = session->v2_data.requested_role;
|
||||
|
||||
/* ULENGTHm */
|
||||
@ -399,11 +416,9 @@ int lanplus_generate_rakp3_authcode(char * output_buffer,
|
||||
printbuf((char*)(session->authcode), IPMI_AUTHCODE_BUFFER_SIZE, ">> rakp3 mac key");
|
||||
}
|
||||
|
||||
|
||||
lanplus_HMAC(session->v2_data.auth_alg,
|
||||
session->authcode,
|
||||
(session->authcode[IPMI_AUTHCODE_BUFFER_SIZE - 1] == 0?
|
||||
strlen(session->authcode): IPMI_AUTHCODE_BUFFER_SIZE),
|
||||
IPMI_AUTHCODE_BUFFER_SIZE,
|
||||
input_buffer,
|
||||
input_buffer_length,
|
||||
output_buffer,
|
||||
@ -451,8 +466,7 @@ int lanplus_generate_sik(struct ipmi_session * session)
|
||||
char * input_buffer;
|
||||
int input_buffer_length, i;
|
||||
char * input_key;
|
||||
int input_key_length;
|
||||
int mac_length;
|
||||
uint32_t mac_length;
|
||||
|
||||
|
||||
memset(session->v2_data.sik, 0, IPMI_SIK_BUFFER_SIZE);
|
||||
@ -460,7 +474,7 @@ int lanplus_generate_sik(struct ipmi_session * session)
|
||||
if (session->v2_data.auth_alg == IPMI_AUTH_RAKP_NONE)
|
||||
return 0;
|
||||
|
||||
/* We don't yet support other alogrithms */
|
||||
/* We don't yet support other algorithms */
|
||||
assert(session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_SHA1);
|
||||
|
||||
input_buffer_length =
|
||||
@ -514,28 +528,25 @@ int lanplus_generate_sik(struct ipmi_session * session)
|
||||
{
|
||||
/* We will be hashing with Kg */
|
||||
/*
|
||||
* TODO: Section 13.31 of the IPMI v2 spec describes the SIK creation
|
||||
* using Kg. It specifies that Kg should not be truncated, but I
|
||||
* do not know what is meant by that.
|
||||
* Section 13.31 of the IPMI v2 spec describes the SIK creation
|
||||
* using Kg. It specifies that Kg should not be truncated.
|
||||
* Kg is set in ipmi_intf.
|
||||
*/
|
||||
lprintf(LOG_ERR, "lanplus_generate_sik: We dont yet support hashing with Kg");
|
||||
assert(0);
|
||||
|
||||
input_key = session->v2_data.kg;
|
||||
input_key_length = strlen(session->v2_data.kg);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We will be hashing with Kuid */
|
||||
input_key = session->authcode;
|
||||
input_key_length = (session->authcode[IPMI_AUTHCODE_BUFFER_SIZE - 1] == 0?
|
||||
strlen(session->authcode): IPMI_AUTHCODE_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
|
||||
if (verbose >= 2)
|
||||
printbuf(input_buffer, input_buffer_length, "session integrity key input");
|
||||
|
||||
lanplus_HMAC(session->v2_data.auth_alg,
|
||||
input_key,
|
||||
input_key_length,
|
||||
IPMI_AUTHCODE_BUFFER_SIZE,
|
||||
input_buffer,
|
||||
input_buffer_length,
|
||||
session->v2_data.sik,
|
||||
@ -583,7 +594,7 @@ int lanplus_generate_k1(struct ipmi_session * session)
|
||||
{
|
||||
lanplus_HMAC(session->v2_data.auth_alg,
|
||||
session->v2_data.sik,
|
||||
20, /* SIK length */
|
||||
IPMI_SIK_BUFFER_SIZE, /* SIK length */
|
||||
CONST_1,
|
||||
20,
|
||||
session->v2_data.k1,
|
||||
@ -626,7 +637,7 @@ int lanplus_generate_k2(struct ipmi_session * session)
|
||||
{
|
||||
lanplus_HMAC(session->v2_data.auth_alg,
|
||||
session->v2_data.sik,
|
||||
20, /* SIK length */
|
||||
IPMI_SIK_BUFFER_SIZE, /* SIK length */
|
||||
CONST_2,
|
||||
20,
|
||||
session->v2_data.k2,
|
||||
@ -675,7 +686,6 @@ int lanplus_encrypt_payload(uint8_t crypt_alg,
|
||||
|
||||
if (crypt_alg == IPMI_CRYPT_NONE)
|
||||
{
|
||||
lprintf(LOG_WARNING, "NOT ENCRYPTING");
|
||||
/* Just copy the input to the output */
|
||||
*bytes_written = input_length;
|
||||
return 0;
|
||||
@ -683,7 +693,7 @@ int lanplus_encrypt_payload(uint8_t crypt_alg,
|
||||
|
||||
/* Currently, we only support AES */
|
||||
assert(crypt_alg == IPMI_CRYPT_AES_CBC_128);
|
||||
assert(input_length <= 255);
|
||||
assert(input_length <= IPMI_MAX_PAYLOAD_SIZE);
|
||||
|
||||
|
||||
/*
|
||||
@ -786,7 +796,7 @@ int lanplus_has_valid_auth_code(struct ipmi_rs * rs,
|
||||
|
||||
lanplus_HMAC(session->v2_data.integrity_alg,
|
||||
session->v2_data.k1,
|
||||
20,
|
||||
IPMI_AUTHCODE_BUFFER_SIZE,
|
||||
rs->data + IMPI_LANPLUS_OFFSET_AUTHTYPE,
|
||||
rs->data_len - IMPI_LANPLUS_OFFSET_AUTHTYPE - IPMI_SHA1_AUTHCODE_SIZE,
|
||||
generated_authcode,
|
||||
|
@ -41,15 +41,20 @@
|
||||
|
||||
/*
|
||||
* See the implementation file for documentation
|
||||
* ipmi_intf can be used for oem specific implementations
|
||||
* e.g. if (ipmi_oem_active(intf, "OEM_XYZ"))
|
||||
*/
|
||||
|
||||
int lanplus_rakp2_hmac_matches(const struct ipmi_session * session,
|
||||
const uint8_t * hmac);
|
||||
const uint8_t * hmac,
|
||||
struct ipmi_intf * intf);
|
||||
int lanplus_rakp4_hmac_matches(const struct ipmi_session * session,
|
||||
const uint8_t * hmac);
|
||||
const uint8_t * hmac,
|
||||
struct ipmi_intf * intf);
|
||||
int lanplus_generate_rakp3_authcode(char * buffer,
|
||||
const struct ipmi_session * session,
|
||||
uint32_t * auth_length);
|
||||
uint32_t * auth_length,
|
||||
struct ipmi_intf * intf);
|
||||
int lanplus_generate_sik(struct ipmi_session * session);
|
||||
int lanplus_generate_k1(struct ipmi_session * session);
|
||||
int lanplus_generate_k2(struct ipmi_session * session);
|
||||
|
@ -34,6 +34,7 @@
|
||||
* facility.
|
||||
*/
|
||||
|
||||
#include "ipmitool/ipmi_constants.h"
|
||||
#include "lanplus.h"
|
||||
#include "lanplus_crypt_impl.h"
|
||||
#include <openssl/hmac.h>
|
||||
@ -79,7 +80,7 @@ int lanplus_seed_prng(uint32_t bytes)
|
||||
int
|
||||
lanplus_rand(uint8_t * buffer, uint32_t num_bytes)
|
||||
{
|
||||
#define IPMI_LANPLUS_FAKE_RAND 1
|
||||
#undef IPMI_LANPLUS_FAKE_RAND
|
||||
#ifdef IPMI_LANPLUS_FAKE_RAND
|
||||
|
||||
/*
|
||||
@ -133,7 +134,7 @@ lanplus_HMAC(uint8_t mac,
|
||||
}
|
||||
|
||||
|
||||
return HMAC(evp_md, key, key_len, d, n, md, md_len);
|
||||
return HMAC(evp_md, key, key_len, d, n, md, (unsigned int *)md_len);
|
||||
}
|
||||
|
||||
|
||||
@ -162,6 +163,7 @@ lanplus_encrypt_aes_cbc_128(const uint8_t * iv,
|
||||
EVP_CIPHER_CTX ctx;
|
||||
EVP_CIPHER_CTX_init(&ctx);
|
||||
EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key, iv);
|
||||
EVP_CIPHER_CTX_set_padding(&ctx, 0);
|
||||
|
||||
|
||||
*bytes_written = 0;
|
||||
@ -185,7 +187,7 @@ lanplus_encrypt_aes_cbc_128(const uint8_t * iv,
|
||||
assert((input_length % IPMI_CRYPT_AES_CBC_128_BLOCK_SIZE) == 0);
|
||||
|
||||
|
||||
if(!EVP_EncryptUpdate(&ctx, output, bytes_written, input, input_length))
|
||||
if(!EVP_EncryptUpdate(&ctx, output, (unsigned int *)bytes_written, input, input_length))
|
||||
{
|
||||
/* Error */
|
||||
*bytes_written = 0;
|
||||
@ -195,7 +197,7 @@ lanplus_encrypt_aes_cbc_128(const uint8_t * iv,
|
||||
{
|
||||
uint32_t tmplen;
|
||||
|
||||
if(!EVP_EncryptFinal_ex(&ctx, output + *bytes_written, &tmplen))
|
||||
if(!EVP_EncryptFinal_ex(&ctx, output + *bytes_written, (unsigned int *)&tmplen))
|
||||
{
|
||||
*bytes_written = 0;
|
||||
return; /* Error */
|
||||
@ -236,6 +238,8 @@ lanplus_decrypt_aes_cbc_128(const uint8_t * iv,
|
||||
EVP_CIPHER_CTX ctx;
|
||||
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)
|
||||
@ -259,7 +263,7 @@ lanplus_decrypt_aes_cbc_128(const uint8_t * iv,
|
||||
assert((input_length % IPMI_CRYPT_AES_CBC_128_BLOCK_SIZE) == 0);
|
||||
|
||||
|
||||
if (!EVP_DecryptUpdate(&ctx, output, bytes_written, input, input_length))
|
||||
if (!EVP_DecryptUpdate(&ctx, output, (unsigned int *)bytes_written, input, input_length))
|
||||
{
|
||||
/* Error */
|
||||
fprintf(stderr, "ERROR: decrypt update failed");
|
||||
@ -270,7 +274,7 @@ lanplus_decrypt_aes_cbc_128(const uint8_t * iv,
|
||||
{
|
||||
uint32_t tmplen;
|
||||
|
||||
if (!EVP_DecryptFinal_ex(&ctx, output + *bytes_written, &tmplen))
|
||||
if (!EVP_DecryptFinal_ex(&ctx, output + *bytes_written, (unsigned int *)&tmplen))
|
||||
{
|
||||
char buffer[1000];
|
||||
ERR_error_string(ERR_get_error(), buffer);
|
||||
|
@ -43,10 +43,13 @@ extern const struct valstr ipmi_auth_algorithms[];
|
||||
extern const struct valstr ipmi_integrity_algorithms[];
|
||||
extern const struct valstr ipmi_encryption_algorithms[];
|
||||
|
||||
#define DUMP_PREFIX_INCOMING "<< "
|
||||
#define DUMP_PREFIX_INCOMING "<<"
|
||||
|
||||
void lanplus_dump_open_session_response(const struct ipmi_rs * rsp)
|
||||
{
|
||||
if (verbose < 2)
|
||||
return;
|
||||
|
||||
printf("%sOPEN SESSION RESPONSE\n", DUMP_PREFIX_INCOMING);
|
||||
|
||||
printf("%s Message tag : 0x%02x\n",
|
||||
@ -63,6 +66,12 @@ void lanplus_dump_open_session_response(const struct ipmi_rs * rsp)
|
||||
printf("%s Console Session ID : 0x%08lx\n",
|
||||
DUMP_PREFIX_INCOMING,
|
||||
(long)rsp->payload.open_session_response.console_id);
|
||||
|
||||
/* only tag, status, privlvl, and console id are returned if error */
|
||||
if (rsp->payload.open_session_response.rakp_return_code !=
|
||||
IPMI_RAKP_STATUS_NO_ERRORS)
|
||||
return;
|
||||
|
||||
printf("%s BMC Session ID : 0x%08lx\n",
|
||||
DUMP_PREFIX_INCOMING,
|
||||
(long)rsp->payload.open_session_response.bmc_id);
|
||||
@ -87,6 +96,9 @@ void lanplus_dump_rakp2_message(const struct ipmi_rs * rsp, uint8_t auth_alg)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (verbose < 2)
|
||||
return;
|
||||
|
||||
printf("%sRAKP 2 MESSAGE\n", DUMP_PREFIX_INCOMING);
|
||||
|
||||
printf("%s Message tag : 0x%02x\n",
|
||||
@ -141,30 +153,23 @@ void lanplus_dump_rakp4_message(const struct ipmi_rs * rsp, uint8_t auth_alg)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (verbose < 2)
|
||||
return;
|
||||
|
||||
printf("%sRAKP 4 MESSAGE\n", DUMP_PREFIX_INCOMING);
|
||||
|
||||
printf("%s Message tag : 0x%02x\n",
|
||||
DUMP_PREFIX_INCOMING,
|
||||
rsp->payload.rakp2_message.message_tag);
|
||||
rsp->payload.rakp4_message.message_tag);
|
||||
|
||||
printf("%s RMCP+ status : %s\n",
|
||||
DUMP_PREFIX_INCOMING,
|
||||
val2str(rsp->payload.rakp2_message.rakp_return_code,
|
||||
val2str(rsp->payload.rakp4_message.rakp_return_code,
|
||||
ipmi_rakp_return_codes));
|
||||
|
||||
printf("%s Console Session ID : 0x%08lx\n",
|
||||
DUMP_PREFIX_INCOMING,
|
||||
(long)rsp->payload.rakp2_message.console_id);
|
||||
|
||||
printf("%s BMC random number : 0x", DUMP_PREFIX_INCOMING);
|
||||
for (i = 0; i < 16; ++i)
|
||||
printf("%02x", rsp->payload.rakp2_message.bmc_rand[i]);
|
||||
printf("\n");
|
||||
|
||||
printf("%s BMC GUID : 0x", DUMP_PREFIX_INCOMING);
|
||||
for (i = 0; i < 16; ++i)
|
||||
printf("%02x", rsp->payload.rakp2_message.bmc_guid[i]);
|
||||
printf("\n");
|
||||
(long)rsp->payload.rakp4_message.console_id);
|
||||
|
||||
switch(auth_alg)
|
||||
{
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "lanplus.h"
|
||||
#include "ipmitool/ipmi_constants.h"
|
||||
|
||||
const struct valstr ipmi_rakp_return_codes[] = {
|
||||
|
||||
@ -17,7 +18,7 @@ const struct valstr ipmi_rakp_return_codes[] = {
|
||||
{ IPMI_RAKP_STATUS_INVALID_NAME_LENGTH, "invalid name length" },
|
||||
{ IPMI_RAKP_STATUS_UNAUTHORIZED_NAME, "unauthorized name" },
|
||||
{ IPMI_RAKP_STATUS_UNAUTHORIZED_GUID, "unauthorized GUID" },
|
||||
{ IPMI_RAKP_STATUS_INVALID_INTEGRITY_CHECK_VALUE, "invlalid integrity check value" },
|
||||
{ IPMI_RAKP_STATUS_INVALID_INTEGRITY_CHECK_VALUE, "invalid integrity check value" },
|
||||
{ IPMI_RAKP_STATUS_INVALID_CONFIDENTIALITY_ALGORITHM, "invalid confidentiality algorithm" },
|
||||
{ IPMI_RAKP_STATUS_NO_CIPHER_SUITE_MATCH, "no matching cipher suite" },
|
||||
{ IPMI_RAKP_STATUS_ILLEGAL_PARAMTER, "illegal parameter" },
|
||||
@ -35,26 +36,4 @@ const struct valstr ipmi_priv_levels[] = {
|
||||
};
|
||||
|
||||
|
||||
const struct valstr ipmi_auth_algorithms[] = {
|
||||
{ IPMI_AUTH_RAKP_NONE, "none" },
|
||||
{ IPMI_AUTH_RAKP_HMAC_SHA1, "hmac_sha1" },
|
||||
{ IPMI_AUTH_RAKP_HMAC_MD5, "hmac_md5" },
|
||||
{ 0, 0 },
|
||||
};
|
||||
|
||||
const struct valstr ipmi_integrity_algorithms[] = {
|
||||
{ IPMI_INTEGRITY_NONE, "none" },
|
||||
{ IPMI_INTEGRITY_HMAC_SHA1_96, "hmac_sha1_96" },
|
||||
{ IPMI_INTEGRITY_HMAC_MD5_128, "hmac_md5_128" },
|
||||
{ IPMI_INTEGRITY_MD5_128 , "md5_128" },
|
||||
{ 0, 0 },
|
||||
};
|
||||
|
||||
const struct valstr ipmi_encryption_algorithms[] = {
|
||||
{ IPMI_CRYPT_NONE, "none" },
|
||||
{ IPMI_CRYPT_AES_CBC_128, "aes_cbc_128" },
|
||||
{ IPMI_CRYPT_XRC4_128, "xrc4_128" },
|
||||
{ IPMI_CRYPT_XRC4_40, "xrc4_40" },
|
||||
{ 0, 0 },
|
||||
};
|
||||
|
||||
|
@ -52,6 +52,7 @@
|
||||
#include <config.h>
|
||||
|
||||
#ifdef HAVE_OPENIPMI_H
|
||||
# include <linux/compiler.h>
|
||||
# include <linux/ipmi.h>
|
||||
#else
|
||||
# include "open.h"
|
||||
@ -61,20 +62,31 @@ 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)
|
||||
{
|
||||
int i = 0;
|
||||
#ifdef INCLUDE_PICMG_GET_DEVICE_LOCATOR
|
||||
struct ipmi_rq req;
|
||||
struct ipmi_rs *rsp;
|
||||
char msg_data;
|
||||
#endif
|
||||
|
||||
intf->fd = open(IPMI_OPENIPMI_DEV, O_RDWR);
|
||||
|
||||
if (intf->fd < 0) {
|
||||
intf->fd = open(IPMI_OPENIPMI_DEVFS, O_RDWR);
|
||||
lperror(LOG_ERR, "Could not open device at %s or %s",
|
||||
IPMI_OPENIPMI_DEV, IPMI_OPENIPMI_DEVFS);
|
||||
if (intf->fd < 0) {
|
||||
intf->fd = open(IPMI_OPENIPMI_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);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ioctl(intf->fd, IPMICTL_SET_GETS_EVENTS_CMD, &i) < 0) {
|
||||
lperror(LOG_ERR, "Could not enable event receiver");
|
||||
@ -90,9 +102,36 @@ ipmi_openipmi_open(struct ipmi_intf * intf)
|
||||
lprintf(LOG_DEBUG, "Set IPMB address to 0x%x",
|
||||
intf->my_addr);
|
||||
}
|
||||
|
||||
intf->opened = 1;
|
||||
|
||||
#ifdef INCLUDE_PICMG_GET_DEVICE_LOCATOR
|
||||
/* PICMG hack to set right IPMB address,
|
||||
we might want to do GetPICMGProperties first.
|
||||
|
||||
In any case, on a server board or a non-picmg IpmC blade , this code
|
||||
will not have any adverse side effect
|
||||
*/
|
||||
if ( (intf->my_addr == IPMI_BMC_SLAVE_ADDR) ) {
|
||||
lprintf(LOG_DEBUG, "Running PICMG GetDeviceLocator" );
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.msg.netfn = IPMI_NETFN_PICMG;
|
||||
req.msg.cmd = 0x01;
|
||||
msg_data = 0x00;
|
||||
req.msg.data = &msg_data;
|
||||
req.msg.data_len = 1;
|
||||
msg_data = 0;
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (rsp) {
|
||||
if ( !rsp->ccode ) {
|
||||
intf->my_addr = rsp->data[2];
|
||||
intf->target_addr = intf->my_addr;
|
||||
lprintf(LOG_DEBUG, "Discovered IPMB address = 0x%x", intf->my_addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return intf->fd;
|
||||
}
|
||||
|
||||
@ -118,6 +157,7 @@ ipmi_openipmi_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
|
||||
};
|
||||
struct ipmi_ipmb_addr ipmb_addr = {
|
||||
addr_type: IPMI_IPMB_ADDR_TYPE,
|
||||
channel: intf->target_channel & 0x0f,
|
||||
};
|
||||
struct ipmi_req _req;
|
||||
static struct ipmi_rs rsp;
|
||||
@ -152,6 +192,7 @@ ipmi_openipmi_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
|
||||
/* otherwise use system interface */
|
||||
lprintf(LOG_DEBUG+2, "Sending request to "
|
||||
"System Interface");
|
||||
bmc_addr.lun = req->msg.lun;
|
||||
_req.addr = (char *) &bmc_addr;
|
||||
_req.addr_len = sizeof(bmc_addr);
|
||||
}
|
||||
@ -171,6 +212,9 @@ ipmi_openipmi_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
|
||||
* wait for and retrieve response
|
||||
*/
|
||||
|
||||
if (intf->noanswer)
|
||||
return NULL;
|
||||
|
||||
FD_ZERO(&rset);
|
||||
FD_SET(intf->fd, &rset);
|
||||
|
||||
|
Reference in New Issue
Block a user