Compare commits

...

93 Commits

Author SHA1 Message Date
d8399dff61 This commit was manufactured by cvs2svn to create tag 'IPMITOOL_1_8_0'. 2005-03-31 17:49:17 +00:00
3fa867b222 swap order of readline/curses linking to fix static compile 2005-03-31 17:49:16 +00:00
8169fc6b3f intf_lan -> lan 2005-03-31 17:42:11 +00:00
505ec7615d don't enable bmc driver on sparc 2005-03-25 23:12:10 +00:00
116c7a7cf9 fix segfault when no entity passed 2005-03-25 16:58:54 +00:00
5c1661707c add patch to allow sel list qualifiers 2005-03-24 19:23:08 +00:00
c105728a9a add rpath for solaris, add darwin config block 2005-03-24 19:10:36 +00:00
08e8e99fe2 remove unused argument from usage text 2005-03-24 18:32:33 +00:00
596ef14553 add usage text for entity and dump commands 2005-03-24 18:31:03 +00:00
0d3daba614 undefine BSWAP_16 and BSWAP_32 so no warnings in case we redefine later 2005-03-24 17:30:59 +00:00
b42a8d7d6f typo alogrithms->algorithms 2005-03-24 01:46:03 +00:00
75ae0675c2 fix error message when de-activating SOL fails 2005-03-24 01:44:26 +00:00
a427845e41 dont print error for missing parameters 2005-03-24 01:39:01 +00:00
d2364e50b2 fix error message display 2005-03-24 01:34:25 +00:00
e05098f802 fix option parsing on isol command 2005-03-24 01:33:37 +00:00
d7e971d92f fix compile error with gcc4 2005-03-21 09:33:52 +00:00
4e59621e64 use double instead of float because its more portable 2005-03-18 00:43:05 +00:00
3da7fea17f solaris 9 doesn't have sqrtf 2005-03-18 00:36:20 +00:00
9c476f36aa bmc interface changes I missed 2005-03-17 23:02:40 +00:00
c575d4b028 update changelog 2005-03-17 18:45:02 +00:00
775f349d04 list bootdev in help instead of bootparam 2005-03-17 17:03:04 +00:00
69c50e3d73 clearer description 2005-03-17 05:00:32 +00:00
e9c27522c0 resurrect wv2 oemtype 2005-03-17 04:59:02 +00:00
14042e4021 sometimes still get valid read when scanning is disabled 2005-03-17 04:39:51 +00:00
47e42d3f32 fix compile errors when -Wall is specified 2005-03-17 03:28:53 +00:00
344cd68cc1 add get guid cmd define 2005-03-17 02:55:41 +00:00
8974794475 fix sel print error 2005-03-17 00:12:32 +00:00
3a96ee3272 update bmc driver for solaris 2005-03-17 00:12:08 +00:00
1fbd130b9b update changelogs 2005-03-17 00:11:13 +00:00
d2bee0687a ressurect isol command 2005-03-17 00:03:14 +00:00
34474dcb2a add linear sensor support 2005-03-16 23:54:12 +00:00
e7f78a54f9 set version 1.8.0 2005-03-16 23:52:12 +00:00
2c87bfc701 fix typos 2005-03-16 23:51:29 +00:00
d4b64f4277 add option to get mc guid 2005-03-16 23:21:22 +00:00
9caeb52ec1 support fru list as well as fru print 2005-03-16 23:20:55 +00:00
b27e296399 fix setting of chassis boot parameters 2005-03-16 23:20:37 +00:00
f29c7e699c support 16bit payload lengths with ipmiv2 2005-03-16 23:17:37 +00:00
04561e2433 fix handling of names with spaces in exec/shell 2005-03-16 23:13:57 +00:00
6d1f8521e6 Removed calls to ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN)
in the sub-commands.  We are ADMIN by default.
2005-03-09 20:29:35 +00:00
90e2c17543 From Holger Liebig. Many changes, primarily to support Intel's v2
capable BMC.  Also includes many general fixes.  Thank you Holger.
2005-03-09 17:16:14 +00:00
1df7ca9588 From Holger Liebig, define IPMI_PAYLOAD_TYPE_OEM 2005-03-09 17:13:35 +00:00
6dae08746d From Holger Liebig. Add support for Intel RMCP+ capabable BMC. 2005-03-09 17:12:44 +00:00
413078f80b Don't use fake random numbers ;-) 2005-03-09 17:11:09 +00:00
e2cd941c34 Allow setting of RMCP+ messaging cipher suite privilege levels 2005-03-08 20:11:48 +00:00
ca85cb4688 Added IPMI_SESSION_PRIV_UNSPECIFIED for the RMCP+ cipher suite priv code 2005-03-08 20:06:29 +00:00
e067d97a41 Now printing "RMCP+ Cipher Suites" and "Cipher Suite Priv Max" data. 2005-03-07 16:35:28 +00:00
ac3e23b9b9 Extended LAN Configuration Parameteres to include RMCP+ related parameters
new to the v2 spec.
2005-03-07 16:34:01 +00:00
a60b6acce1 Usage statement change "authentication" ==> "auth" in order to keep
column width < 80 characters.
2005-03-07 14:00:56 +00:00
daf5180838 Contribution by Holger Liebig. Better error handling, graceful handling
of unsupported options and human readable error output.
2005-03-04 21:39:50 +00:00
3979342536 Disable block padding in OpenSSL encryption/decryption 2005-03-03 20:02:51 +00:00
a12c0c31bb The session ID and sequence numbers should be set to 0 in pre-session. 2005-02-25 20:05:31 +00:00
7094b4f838 Correct comment in return code description for lanplus_rakp4_matches 2005-02-23 20:54:06 +00:00
f0b24c9a0e remove inaccurate assert. 2005-02-23 16:29:55 +00:00
674eb706a3 Fix bug in argument processing for sol channel 2005-02-17 22:35:52 +00:00
fe4f77cfdd Corrected misspelling Parial ==> Partial 2005-02-17 22:27:43 +00:00
cd5ee61d23 Added implementation for "channel getciphers" which implements the
command Get Channel Cipher Suites.
2005-02-17 22:26:08 +00:00
f7dc0a57de Move algorithm ID definitions into the higher level ipmi_constants.h file 2005-02-17 22:24:38 +00:00
c6db0382e5 move some strings (for algorithm descriptions) into a the higher level
ipmi_strings.[c|h] file.
2005-02-17 22:22:40 +00:00
761ce85d28 include the numeric error code if it's available. 2005-02-16 22:33:02 +00:00
3d29ed01a5 Fix 2 minor bugs in output. 1) if a field didn't exist, we weren't
updating our offset.  This caused subsequent fields to not be displayed.
2) Add missing field "Board Mfg".  I think this was just an oversight
during a rewrite.
2005-02-16 20:12:06 +00:00
bc17282c3a Per request from fujitsu-siemens, don't pad username in RAKP1 message 2005-02-10 17:15:48 +00:00
247ad8f661 Corrected size of RAKP1 messages (43 ==> 44) 2005-02-10 17:14:54 +00:00
5679de9984 Added some debugging output 2005-02-09 19:30:33 +00:00
15ed988689 User cipher suite as specified by the user (with -C). We now support
integrity and encryption algorithms of NONE.  Also fixed where we were
using the auth algorithm in places where the integrity albums was supposed
to be used.
2005-02-09 19:29:19 +00:00
34ddf53870 Added the -C option so that a user can specify a cipher suite ID. This
cipher suite ID indicates which authentication, integrity and
encryption algorithms should be used form IPMIv2 RMCP+ (lanplus) sessions.
2005-02-09 19:26:45 +00:00
42e73b39de Added ability to store and set the requested cipher suite ID
and its alogorithm specifiers.
2005-02-09 19:24:08 +00:00
aca415c287 fix rmcp ping/pong handling for network-byte-order 2005-02-09 17:42:13 +00:00
c4699aba9c A one-off error was preventing a output of the last user. This was caught
by Anthony Yeung at Newisys.
2005-02-08 19:15:37 +00:00
be2c0c4b03 Set rsp->data_len to 0 if there is not response data. 2005-02-04 18:46:15 +00:00
0d72cd27cc Increase the data buffer size of raw packet data. Also avoid buffer
overflows with this data.
2005-02-02 20:47:11 +00:00
e4ba0c3de3 fix sel list return code 2005-02-02 17:28:03 +00:00
96bd14b905 fix authtype setting parameters 2005-02-01 16:28:32 +00:00
8a2a11c520 checking invalid return code for feof 2005-02-01 00:14:37 +00:00
9164d3b69e incorrect bigendian define was messing up fru locator records 2005-02-01 00:13:34 +00:00
80a9f3acb2 return success on poh command 2005-02-01 00:08:04 +00:00
94f272e8e2 don't dump packets unless verbose is given twice 2005-02-01 00:07:19 +00:00
682caca7ea converted some spaces into tabs for consistency 2005-01-28 15:47:14 +00:00
d6274af150 Added text indicating whether threshold crossings are assertion or
deassertion events.  This fix is submitted for Wes Bemont at Newisys.
2005-01-28 15:45:39 +00:00
1d7e045d47 don't return failure code on timeouts 2005-01-27 17:41:48 +00:00
8dd12afdad explicit return value when printing analog sensors 2005-01-27 17:39:30 +00:00
174b13e835 set logpriv to null on log_halt 2005-01-21 23:10:57 +00:00
ff89a0e2f2 fix debug output formatting 2005-01-21 16:07:06 +00:00
9dbab242bd fix segfault when setting auth levels 2005-01-21 16:06:03 +00:00
658b502e64 trim extra bytes from data 2005-01-21 16:04:34 +00:00
b8d8587b2a exit status 0 when printing usage help. add bmc command aliased to mc command 2005-01-19 17:25:25 +00:00
445025f2f4 stop printing lan parameters if one returns an error other than 0x80 2005-01-18 17:01:00 +00:00
55ee755de8 cygwin needs inet_aton 2005-01-18 16:49:43 +00:00
e9281ea912 set specific options for building under cygwin 2005-01-12 21:14:55 +00:00
58ef4f8af6 move enum flg_e enum define to header file and make sure ipmi_pef_print_flags() prototype is correct 2005-01-12 21:13:25 +00:00
2e5d0c2921 cygwin does not have inet_ntop() function so do manual print of ip addresses on windows 2005-01-12 21:12:19 +00:00
79421577cc change input type to uint32_t instead of int 2005-01-12 21:11:12 +00:00
651466fc41 use inet_aton instead of inet_pton for compatibility 2005-01-12 21:08:56 +00:00
072986b669 fix compiler warnings related to types, use inet_aton instead of inet_pton for compatibility 2005-01-12 21:05:42 +00:00
51 changed files with 2402 additions and 691 deletions

View File

@ -1,3 +1,12 @@
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 version 1.7.0
* Propogate errors correctly so exit status will be useful * Propogate errors correctly so exit status will be useful
* More consistent display of errors including completion code text * More consistent display of errors including completion code text

View File

@ -3,7 +3,7 @@ dnl autoconf for ipmitool
dnl dnl
AC_INIT([src/ipmitool.c]) AC_INIT([src/ipmitool.c])
AC_CANONICAL_SYSTEM AC_CANONICAL_SYSTEM
AM_INIT_AUTOMAKE([ipmitool], [1.7.0]) AM_INIT_AUTOMAKE([ipmitool], [1.8.0])
AM_CONFIG_HEADER(config.h) AM_CONFIG_HEADER(config.h)
AC_CONFIG_SRCDIR([src/ipmitool.c]) AC_CONFIG_SRCDIR([src/ipmitool.c])
AC_PREREQ(2.50) AC_PREREQ(2.50)
@ -58,13 +58,38 @@ solaris*)
STRIP=gstrip STRIP=gstrip
LD=gld LD=gld
AR=gar AR=gar
# openssl libs are in /usr/sfw/lib on solaris 10
LIBS="$LIBS -R/usr/sfw/lib"
# disable the linux-specific interfaces # disable the linux-specific interfaces
enable_intf_bmc=yes # 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_imb=no
enable_intf_open=no enable_intf_open=no
enable_ipmievd=no enable_ipmievd=no
enable_ipmishell=no enable_ipmishell=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_ipmievd=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_ipmived=no
enable_ipmishell=no
;;
esac esac
AC_SUBST(ARCH, $host_cpu) AC_SUBST(ARCH, $host_cpu)
@ -162,7 +187,7 @@ AC_CHECK_HEADER([linux/ipmi.h],
dnl enable Linux OpenIPMI interface dnl enable Linux OpenIPMI interface
AC_ARG_ENABLE([intf-open], AC_ARG_ENABLE([intf-open],
[AC_HELP_STRING([--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]) [], [enable_intf_open=yes])
if test "x$enable_intf_open" = "xstatic" || test "x$enable_intf_open" = "xplugin"; then if test "x$enable_intf_open" = "xstatic" || test "x$enable_intf_open" = "xplugin"; then
enable_intf_open=yes enable_intf_open=yes
@ -177,7 +202,7 @@ fi
dnl enable Intel IMB interface dnl enable Intel IMB interface
AC_ARG_ENABLE([intf-imb], AC_ARG_ENABLE([intf-imb],
[AC_HELP_STRING([--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]) [], [enable_intf_imb=yes])
if test "x$enable_intf_imb" = "xstatic" || test "x$enable_intf_imb" = "xplugin"; then if test "x$enable_intf_imb" = "xstatic" || test "x$enable_intf_imb" = "xplugin"; then
enable_intf_imb=yes enable_intf_imb=yes
@ -212,7 +237,7 @@ fi
dnl enable Solaris BMC interface dnl enable Solaris BMC interface
AC_ARG_ENABLE([intf-bmc], AC_ARG_ENABLE([intf-bmc],
[AC_HELP_STRING([--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]) [enable_intf_bmc=no])
if test "x$enable_intf_bmc" = "xstatic" || test "x$enable_intf_bmc" = "xplugin"; then if test "x$enable_intf_bmc" = "xstatic" || test "x$enable_intf_bmc" = "xplugin"; then
enable_intf_bmc=yes enable_intf_bmc=yes
@ -232,8 +257,8 @@ AC_ARG_ENABLE([ipmishell],
[enable IPMI shell interface [default=yes]])], [enable IPMI shell interface [default=yes]])],
[], [enable_ipmishell=yes]) [], [enable_ipmishell=yes])
if test "x$enable_ipmishell" = "xyes"; then if test "x$enable_ipmishell" = "xyes"; then
AC_SEARCH_LIBS([initscr], [curses ncurses], [have_curses=yes])
AC_SEARCH_LIBS([readline], [readline], [have_readline=yes]) AC_SEARCH_LIBS([readline], [readline], [have_readline=yes])
AC_SEARCH_LIBS([initscr], [curses ncurses], [have_curses=yes])
if test "x$have_curses" = "xyes" && test "x$have_readline" = "xyes"; then if test "x$have_curses" = "xyes" && test "x$have_readline" = "xyes"; then
AC_DEFINE(HAVE_READLINE, [1], [Define to 1 if readline present.]) AC_DEFINE(HAVE_READLINE, [1], [Define to 1 if readline present.])
fi fi
@ -242,7 +267,7 @@ fi
dnl enable IPMI Event Daemon dnl enable IPMI Event Daemon
AC_ARG_ENABLE([ipmievd], AC_ARG_ENABLE([ipmievd],
[AC_HELP_STRING([--enable-ipmievd], [AC_HELP_STRING([--enable-ipmievd],
[enable IPMI Event daemon [default=yes]])], [enable IPMI Event daemon [default=auto]])],
[], [enable_ipmievd=yes]) [], [enable_ipmievd=yes])
AM_CONDITIONAL(IPMIEVD, [test "x$enable_ipmievd" = "xyes"]) AM_CONDITIONAL(IPMIEVD, [test "x$enable_ipmievd" = "xyes"])
if test "x$enable_ipmievd" = "xyes"; then if test "x$enable_ipmievd" = "xyes"; then

View File

@ -58,6 +58,28 @@ rm -rf $RPM_BUILD_DIR/ipmitool-@VERSION@
%doc %{_datadir}/doc/ipmitool/* %doc %{_datadir}/doc/ipmitool/*
%changelog %changelog
* 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 * Wed Aug 18 2004 <duncan@iceblink.org> 1.6.0-1
- Add a README - Add a README
- Add support for IPMIv2 and Serial-over-LAN from Newisys - Add support for IPMIv2 and Serial-over-LAN from Newisys

View File

@ -1,3 +1,18 @@
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 ipmitool (1.7.0) unstable; urgency=low
* Propogate errors correctly so exit status will be useful * Propogate errors correctly so exit status will be useful

View File

@ -41,10 +41,10 @@ Remote server address, can be IP address or hostname. This option is required f
Remote username, default is NULL user. Remote username, default is NULL user.
.TP .TP
\fB\-L\fR <\fIprivlvl\fP> \fB\-L\fR <\fIprivlvl\fP>
Force sessin privilege level. Can be CALLBACK, USER, OPERATOR, ADMIN. Default is ADMIN. Force session privilege level. Can be CALLBACK, USER, OPERATOR, ADMIN. Default is ADMIN.
.TP .TP
\fB\-a\fR \fB\-a\fR
Promt for the remote server password, 16 character maximum. This is optional for the LAN interface, if a password is not provided the session will not be authenticated. Prompt for the remote server password, 16 character maximum. This is optional for the LAN interface, if a password is not provided the session will not be authenticated.
.TP .TP
\fB\-E\fR \fB\-E\fR
The remote server password is specified by the environment variable \fBIPMI_PASSWORD\fR. This option is intended for shell scripts. The remote server password is specified by the environment variable \fBIPMI_PASSWORD\fR. This option is intended for shell scripts.
@ -95,10 +95,10 @@ RAW RSP (5 bytes)
.RS .RS
.TP .TP
\fIauthcap\fP <\fBchannel number\fR> <\fBmax priv\fR> \fIauthcap\fP <\fBchannel number\fR> <\fBmax priv\fR>
This command will display information about the authentication capabilities of the slected channel at the specified privelige level. This command will display information about the authentication capabilities of the selected channel at the specified privelige level.
.RS .RS
.TP .TP
Possible privelige levels are: Possible privilege levels are:
.br .br
1 Callback level 1 Callback level
.br .br
@ -462,7 +462,7 @@ Special escape sequences are provided to control the SOL session:
.RS .RS
.TP .TP
.I deactivate .I deactivate
This command deactives Serial Over LAN mode on the BMC. Exiting Serial Over LAN mode should automatically cause this command to be sent to the BMC, but in the case of an unintentional exit from SOL mode, this command may be necessary to reset the state the BMC. This command deactivates Serial Over LAN mode on the BMC. Exiting Serial Over LAN mode should automatically cause this command to be sent to the BMC, but in the case of an unintentional exit from SOL mode, this command may be necessary to reset the state of the BMC.
.RE .RE
.RE .RE
.SH "OPEN INTERFACE" .SH "OPEN INTERFACE"
@ -506,10 +506,10 @@ You can tell ipmitool to use the lan interface with the \fB\-I\fR option:
.PP .PP
ipmitool \-I lan \-H <hostname> [\-U username] [\-P password] <expression> ipmitool \-I lan \-H <hostname> [\-U username] [\-P password] <expression>
.LP .LP
A hostname \fBmust\fR be given on the command line in order to use the lan interface with ipmitool. The password field is optional; if you do not provide a password on the command line ipmitool will attempt to connect without authentication. If you specify a password it will use MD5 authentication if supported by the BMC and straight password/key otherwise. A hostname \fBmust\fR be given on the command line in order to use the lan interface with ipmitool. The password field is optional; if you do not provide a password on the command line, ipmitool will attempt to connect without authentication. If you specify a password it will use MD5 authentication if supported by the BMC and straight password/key otherwise.
.SH "LANPLUS INTERFACE" .SH "LANPLUS INTERFACE"
.LP .LP
Like the \fIlan\fP inteface, the \fIlanplus\fP interface communicates with the BMC over an Ethernet LAN connection using UDP under IPv4. The difference is that the \fIlanplus\fP interface uses the RMCP+ protocol as described in the IMPI v2.0 specification. RMCP+ allows for improved authentication and data integrity checks, as well as encryption and the ability to carry multiple types of payloads. Generic Serial Over LAN support requires RMCP+, so the ipmitool \fIsol activate\fP command requires the use of the \fIlanplus\fP interface. Like the \fIlan\fP interface, the \fIlanplus\fP interface communicates with the BMC over an Ethernet LAN connection using UDP under IPv4. The difference is that the \fIlanplus\fP interface uses the RMCP+ protocol as described in the IMPI v2.0 specification. RMCP+ allows for improved authentication and data integrity checks, as well as encryption and the ability to carry multiple types of payloads. Generic Serial Over LAN support requires RMCP+, so the ipmitool \fIsol activate\fP command requires the use of the \fIlanplus\fP interface.
.LP .LP
RMCP+ session establishment uses a protocol call RAKP (Remote Authenticated Key-Exchange Protocol) which allows the negotiation of many options. ipmitool does not yet allow the user to specify the value of every option, defaulting to the most obvious settings, marked as required in the v2.0 specification. Authentication and integrity HMACS are produced with SHA1, and encryption is performed with AES-CBC-128. Role-level logins are not supported. ipmitool must be configured with the appropriate option for the \fIlanplus\fP interface to be available, as it is not enabled by default. This interface currently requires the OpenSSL library. RMCP+ session establishment uses a protocol call RAKP (Remote Authenticated Key-Exchange Protocol) which allows the negotiation of many options. ipmitool does not yet allow the user to specify the value of every option, defaulting to the most obvious settings, marked as required in the v2.0 specification. Authentication and integrity HMACS are produced with SHA1, and encryption is performed with AES-CBC-128. Role-level logins are not supported. ipmitool must be configured with the appropriate option for the \fIlanplus\fP interface to be available, as it is not enabled by default. This interface currently requires the OpenSSL library.
.LP .LP

View File

@ -39,5 +39,5 @@ 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_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_channel.h ipmi_sensor.h ipmi_event.h ipmi_session.h \
ipmi_strings.h ipmi_constants.h ipmi_user.h ipmi_pef.h \ ipmi_strings.h ipmi_constants.h ipmi_user.h ipmi_pef.h \
ipmi_oem.h ipmi_oem.h ipmi_isol.h

View File

@ -41,6 +41,9 @@
# include <config.h> # include <config.h>
#endif #endif
#undef BSWAP_16
#undef BSWAP_32
#if HAVE_BYTESWAP_H #if HAVE_BYTESWAP_H
# include <byteswap.h> # include <byteswap.h>
# define BSWAP_16(x) bswap_16(x) # define BSWAP_16(x) bswap_16(x)

View File

@ -49,6 +49,7 @@
/* From table 13.16 of the IPMI v2 specification */ /* From table 13.16 of the IPMI v2 specification */
#define IPMI_PAYLOAD_TYPE_IPMI 0x00 #define IPMI_PAYLOAD_TYPE_IPMI 0x00
#define IPMI_PAYLOAD_TYPE_SOL 0x01 #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_REQUEST 0x10
#define IPMI_PAYLOAD_TYPE_RMCP_OPEN_RESPONSE 0x11 #define IPMI_PAYLOAD_TYPE_RMCP_OPEN_RESPONSE 0x11
#define IPMI_PAYLOAD_TYPE_RAKP_1 0x12 #define IPMI_PAYLOAD_TYPE_RAKP_1 0x12

View File

@ -42,14 +42,16 @@
#endif #endif
#include <ipmitool/ipmi.h> #include <ipmitool/ipmi.h>
#define IPMI_GET_CHANNEL_AUTH_CAP 0x38
#define IPMI_GET_CHANNEL_ACCESS 0x41 #define IPMI_GET_CHANNEL_AUTH_CAP 0x38
#define IPMI_GET_CHANNEL_INFO 0x42 #define IPMI_GET_CHANNEL_ACCESS 0x41
#define IPMI_SET_USER_ACCESS 0x43 #define IPMI_GET_CHANNEL_INFO 0x42
#define IPMI_GET_USER_ACCESS 0x44 #define IPMI_SET_USER_ACCESS 0x43
#define IPMI_SET_USER_NAME 0x45 #define IPMI_GET_USER_ACCESS 0x44
#define IPMI_GET_USER_NAME 0x46 #define IPMI_SET_USER_NAME 0x45
#define IPMI_SET_USER_PASSWORD 0x47 #define IPMI_GET_USER_NAME 0x46
#define IPMI_SET_USER_PASSWORD 0x47
#define IPMI_GET_CHANNEL_CIPHER_SUITES 0x54
/* /*

View File

@ -70,6 +70,7 @@
#define IPMI_SESSION_AUTHTYPE_OEM 0x5 #define IPMI_SESSION_AUTHTYPE_OEM 0x5
#define IPMI_SESSION_AUTHTYPE_RMCP_PLUS 0x6 #define IPMI_SESSION_AUTHTYPE_RMCP_PLUS 0x6
#define IPMI_SESSION_PRIV_UNSPECIFIED 0x0
#define IPMI_SESSION_PRIV_CALLBACK 0x1 #define IPMI_SESSION_PRIV_CALLBACK 0x1
#define IPMI_SESSION_PRIV_USER 0x2 #define IPMI_SESSION_PRIV_USER 0x2
#define IPMI_SESSION_PRIV_OPERATOR 0x3 #define IPMI_SESSION_PRIV_OPERATOR 0x3
@ -94,4 +95,21 @@
#define IPMI_CHANNEL_MEDIUM_USB_2 0xb #define IPMI_CHANNEL_MEDIUM_USB_2 0xb
#define IPMI_CHANNEL_MEDIUM_SYSTEM 0xc #define IPMI_CHANNEL_MEDIUM_SYSTEM 0xc
/* 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*/ #endif /*IPMI_CONSTANTS_H*/

View File

@ -81,6 +81,7 @@ struct ipmi_session {
uint8_t authstatus; uint8_t authstatus;
uint8_t authextra; uint8_t authextra;
uint8_t privlvl; uint8_t privlvl;
uint8_t cipher_suite_id;
int password; int password;
int port; int port;
int active; int active;
@ -100,6 +101,9 @@ struct ipmi_session {
enum LANPLUS_SESSION_STATE session_state; enum LANPLUS_SESSION_STATE session_state;
/* These are the algorithms agreed upon for the session */ /* 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 auth_alg;
uint8_t integrity_alg; uint8_t integrity_alg;
uint8_t crypt_alg; uint8_t crypt_alg;
@ -173,6 +177,7 @@ void ipmi_intf_session_set_hostname(struct ipmi_intf * intf, char * hostname);
void ipmi_intf_session_set_username(struct ipmi_intf * intf, char * username); void ipmi_intf_session_set_username(struct ipmi_intf * intf, char * username);
void ipmi_intf_session_set_password(struct ipmi_intf * intf, char * password); 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_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_port(struct ipmi_intf * intf, int port); 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_authtype(struct ipmi_intf * intf, uint8_t authtype);
void ipmi_cleanup(struct ipmi_intf * intf); void ipmi_cleanup(struct ipmi_intf * intf);

View 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 */

View File

@ -60,21 +60,26 @@ enum {
IPMI_LANP_AUTH_TYPE_ENABLE, IPMI_LANP_AUTH_TYPE_ENABLE,
IPMI_LANP_IP_ADDR, IPMI_LANP_IP_ADDR,
IPMI_LANP_IP_ADDR_SRC, IPMI_LANP_IP_ADDR_SRC,
IPMI_LANP_MAC_ADDR, IPMI_LANP_MAC_ADDR, /* 5 */
IPMI_LANP_SUBNET_MASK, IPMI_LANP_SUBNET_MASK,
IPMI_LANP_IP_HEADER, IPMI_LANP_IP_HEADER,
IPMI_LANP_PRI_RMCP_PORT, IPMI_LANP_PRI_RMCP_PORT,
IPMI_LANP_SEC_RMCP_PORT, IPMI_LANP_SEC_RMCP_PORT,
IPMI_LANP_BMC_ARP, IPMI_LANP_BMC_ARP, /* 10 */
IPMI_LANP_GRAT_ARP, IPMI_LANP_GRAT_ARP,
IPMI_LANP_DEF_GATEWAY_IP, IPMI_LANP_DEF_GATEWAY_IP,
IPMI_LANP_DEF_GATEWAY_MAC, IPMI_LANP_DEF_GATEWAY_MAC,
IPMI_LANP_BAK_GATEWAY_IP, IPMI_LANP_BAK_GATEWAY_IP,
IPMI_LANP_BAK_GATEWAY_MAC, IPMI_LANP_BAK_GATEWAY_MAC, /* 15 */
IPMI_LANP_SNMP_STRING, IPMI_LANP_SNMP_STRING,
IPMI_LANP_NUM_DEST, IPMI_LANP_NUM_DEST,
IPMI_LANP_DEST_TYPE, IPMI_LANP_DEST_TYPE,
IPMI_LANP_DEST_ADDR, 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_OEM_ALERT_STRING=96,
IPMI_LANP_ALERT_RETRY=97, IPMI_LANP_ALERT_RETRY=97,
IPMI_LANP_UTC_OFFSET=98, IPMI_LANP_UTC_OFFSET=98,
@ -96,27 +101,32 @@ static struct lan_param {
{ IPMI_LANP_AUTH_TYPE_ENABLE, 5, "Auth Type Enable" }, { IPMI_LANP_AUTH_TYPE_ENABLE, 5, "Auth Type Enable" },
{ IPMI_LANP_IP_ADDR, 4, "IP Address" }, { IPMI_LANP_IP_ADDR, 4, "IP Address" },
{ IPMI_LANP_IP_ADDR_SRC, 1, "IP Address Source" }, { 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_SUBNET_MASK, 4, "Subnet Mask" },
{ IPMI_LANP_IP_HEADER, 3, "IP Header" }, { IPMI_LANP_IP_HEADER, 3, "IP Header" },
{ IPMI_LANP_PRI_RMCP_PORT, 2, "Primary RMCP Port" }, { IPMI_LANP_PRI_RMCP_PORT, 2, "Primary RMCP Port" },
{ IPMI_LANP_SEC_RMCP_PORT, 2, "Secondary 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_GRAT_ARP, 1, "Gratituous ARP Intrvl" },
{ IPMI_LANP_DEF_GATEWAY_IP, 4, "Default Gateway IP" }, { IPMI_LANP_DEF_GATEWAY_IP, 4, "Default Gateway IP" },
{ IPMI_LANP_DEF_GATEWAY_MAC, 6, "Default Gateway MAC" }, { IPMI_LANP_DEF_GATEWAY_MAC, 6, "Default Gateway MAC" },
{ IPMI_LANP_BAK_GATEWAY_IP, 4, "Backup Gateway IP" }, { 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_SNMP_STRING, 18, "SNMP Community String" },
{ IPMI_LANP_NUM_DEST, 1, "Number of Destinations"}, { IPMI_LANP_NUM_DEST, 1, "Number of Destinations"},
{ IPMI_LANP_DEST_TYPE, 4, "Destination Type" }, { IPMI_LANP_DEST_TYPE, 4, "Destination Type" },
{ IPMI_LANP_DEST_ADDR, 13, "Destination Addresses" }, { 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_ALERT_RETRY, 1, "Alert Retry Algorithm" },
{ IPMI_LANP_UTC_OFFSET, 3, "UTC Offset" }, { IPMI_LANP_UTC_OFFSET, 3, "UTC Offset" },
{ IPMI_LANP_DHCP_SERVER_IP, 4, "DHCP Server IP" }, { IPMI_LANP_DHCP_SERVER_IP, 4, "DHCP Server IP" },
{ IPMI_LANP_DHCP_SERVER_MAC, 6, "DHDP Server MAC" }, { 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" }, { IPMI_LANP_CHAN_ACCESS_MODE, 2, "Channel Access Mode" },
{ -1 } { -1 }
}; };

View File

@ -45,6 +45,7 @@
#define BMC_GET_SELF_TEST 0x04 #define BMC_GET_SELF_TEST 0x04
#define BMC_SET_GLOBAL_ENABLES 0x2e #define BMC_SET_GLOBAL_ENABLES 0x2e
#define BMC_GET_GLOBAL_ENABLES 0x2f #define BMC_GET_GLOBAL_ENABLES 0x2f
#define BMC_GET_GUID 0x37
int ipmi_mc_main(struct ipmi_intf *, int, char **); int ipmi_mc_main(struct ipmi_intf *, int, char **);

View File

@ -47,6 +47,13 @@ struct pef_capabilities { /* "get pef capabilities" response */
uint8_t tblsize; uint8_t tblsize;
}; };
typedef enum {
P_TRUE,
P_SUPP,
P_ACTV,
P_ABLE,
} flg_e;
struct pef_table_entry { struct pef_table_entry {
#define PEF_CONFIG_ENABLED 0x80 #define PEF_CONFIG_ENABLED 0x80
#define PEF_CONFIG_PRECONFIGURED 0x40 #define PEF_CONFIG_PRECONFIGURED 0x40
@ -769,7 +776,7 @@ BIT_DESC_MAP_LIST,
#define IPMI_CMD_SERIAL_GET_CONFIG 0x11 #define IPMI_CMD_SERIAL_GET_CONFIG 0x11
const char * ipmi_pef_bit_desc(struct bit_desc_map * map, uint32_t val); 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_dec(const char * text, uint32_t val);
void ipmi_pef_print_hex(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); void ipmi_pef_print_1xd(const char * text, uint32_t val);

View File

@ -381,6 +381,20 @@ struct sdr_record_full_sensor {
} type; } type;
} unit; } 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 */ uint8_t linearization; /* 70h=non linear, 71h-7Fh=non linear, OEM */
uint16_t mtol; /* M, tolerance */ uint16_t mtol; /* M, tolerance */
uint32_t bacc; /* accuracy, B, Bexp, Rexp */ uint32_t bacc; /* accuracy, B, Bexp, Rexp */
@ -457,22 +471,22 @@ struct sdr_record_fru_locator {
uint8_t dev_slave_addr; uint8_t dev_slave_addr;
uint8_t device_id; uint8_t device_id;
#if WORDS_BIGENDIAN #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 #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 #endif
#if WORDS_BIGENDIAN #if WORDS_BIGENDIAN
uint8_t __reserved3 : 4;
uint8_t channel_num : 4; uint8_t channel_num : 4;
uint8_t __reserved3 : 4;
#else #else
uint8_t channel_num : 4;
uint8_t __reserved3 : 4; uint8_t __reserved3 : 4;
uint8_t channel_num : 4;
#endif #endif
uint8_t __reserved4; uint8_t __reserved4;
uint8_t dev_type; uint8_t dev_type;
@ -593,8 +607,8 @@ 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_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); int ipmi_sdr_print_listentry(struct ipmi_intf * intf, struct sdr_record_list * entry);
const char * ipmi_sdr_get_status(uint8_t stat); const char * ipmi_sdr_get_status(uint8_t stat);
float sdr_convert_sensor_reading(struct sdr_record_full_sensor * sensor, uint8_t val); 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, float 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(struct ipmi_intf * intf, uint8_t sensor);
const char * ipmi_sdr_get_sensor_type_desc(const uint8_t type); const char * ipmi_sdr_get_sensor_type_desc(const uint8_t type);

View File

@ -51,5 +51,9 @@ extern const struct valstr ipmi_authtype_session_vals[];
extern const struct valstr ipmi_authtype_vals[]; extern const struct valstr ipmi_authtype_vals[];
extern const struct valstr ipmi_channel_protocol_vals[]; extern const struct valstr ipmi_channel_protocol_vals[];
extern const struct valstr ipmi_channel_medium_vals[]; extern const struct valstr ipmi_channel_medium_vals[];
extern const struct valstr ipmi_auth_algorithms[];
extern const struct valstr ipmi_integrity_algorithms[];
extern const struct valstr ipmi_encryption_algorithms[];
#endif /*IPMI_STRINGS_H*/ #endif /*IPMI_STRINGS_H*/

View File

@ -40,7 +40,7 @@ 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 \ 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 \ 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_session.c ipmi_strings.c ipmi_user.c ipmi_raw.c \
ipmi_oem.c ipmi_oem.c ipmi_isol.c
libipmitool_la_LDFLAGS = -export-dynamic libipmitool_la_LDFLAGS = -export-dynamic
libipmitool_la_LIBADD = -lm libipmitool_la_LIBADD = -lm
libipmitool_la_DEPENDENCIES = libipmitool_la_DEPENDENCIES =

View File

@ -733,6 +733,11 @@ ipmi_spd_print(struct ipmi_intf * intf, uint8_t id)
if (rsp->ccode > 0) { if (rsp->ccode > 0) {
printf(" Device not present (%s)\n", printf(" Device not present (%s)\n",
val2str(rsp->ccode, completion_code_vals)); val2str(rsp->ccode, completion_code_vals));
/* Timeouts are acceptable. No DIMM in the socket */
if (rsp->ccode == 0xc3)
return 1;
return -1; return -1;
} }

View File

@ -39,6 +39,7 @@
#include <inttypes.h> #include <inttypes.h>
#include <signal.h> #include <signal.h>
#include <string.h> #include <string.h>
#include <strings.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <unistd.h>

View File

@ -37,6 +37,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <strings.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
@ -54,6 +55,9 @@
#include <ipmitool/ipmi_strings.h> #include <ipmitool/ipmi_strings.h>
#include <ipmitool/ipmi_constants.h> #include <ipmitool/ipmi_constants.h>
extern int csv_output;
extern int verbose;
void printf_channel_usage (void); void printf_channel_usage (void);
/** /**
@ -353,8 +357,6 @@ ipmi_get_user_access(struct ipmi_intf * intf, uint8_t channel, uint8_t userid)
struct get_user_access_rsp user_access; struct get_user_access_rsp user_access;
int curr_uid, max_uid = 0, init = 1; int curr_uid, max_uid = 0, init = 1;
ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN);
curr_uid = userid ? : 1; curr_uid = userid ? : 1;
memset(&req1, 0, sizeof(req1)); memset(&req1, 0, sizeof(req1));
@ -441,8 +443,6 @@ ipmi_set_user_access(struct ipmi_intf * intf, int argc, char ** argv)
struct set_user_access_data set_access; struct set_user_access_data set_access;
int i; int i;
ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN);
if ((argc < 3) || (strncmp(argv[0], "help", 4) == 0)) { if ((argc < 3) || (strncmp(argv[0], "help", 4) == 0)) {
printf_channel_usage(); printf_channel_usage();
return 0; return 0;
@ -526,6 +526,205 @@ ipmi_set_user_access(struct ipmi_intf * intf, int argc, char ** argv)
return 0; 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 * which,
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] = ((strncmp(which, "all", 3) == 0)? 0x80: 0);
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 uint8_t
ipmi_get_channel_medium(struct ipmi_intf * intf, uint8_t channel) ipmi_get_channel_medium(struct ipmi_intf * intf, uint8_t channel)
{ {
@ -571,7 +770,8 @@ printf_channel_usage()
lprintf(LOG_NOTICE, " getaccess <channel number> [user id]"); lprintf(LOG_NOTICE, " getaccess <channel number> [user id]");
lprintf(LOG_NOTICE, " setaccess <channel number> " lprintf(LOG_NOTICE, " setaccess <channel number> "
"<user id> [callin=on|off] [ipmi=on|off] [link=on|off] [privilege=level]"); "<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 <all | supported> <ipmi | sol> [channel]\n");
lprintf(LOG_NOTICE, "Possible privilege levels are:"); lprintf(LOG_NOTICE, "Possible privilege levels are:");
lprintf(LOG_NOTICE, " 1 Callback level"); lprintf(LOG_NOTICE, " 1 Callback level");
lprintf(LOG_NOTICE, " 2 User level"); lprintf(LOG_NOTICE, " 2 User level");
@ -627,6 +827,25 @@ ipmi_channel_main(struct ipmi_intf * intf, int argc, char ** argv)
retval = ipmi_get_channel_info(intf, ch); retval = ipmi_get_channel_info(intf, ch);
} }
} }
// it channel getciphers <all | supported> <ipmi | sol> [channel]
else if (strncmp(argv[0], "getciphers", 10) == 0)
{
if ((argc < 3) || (argc > 4) ||
(strncmp(argv[1], "all", 3) && strncmp(argv[1], "supported", 9)) ||
(strncmp(argv[2], "ipmi", 4) && strncmp(argv[2], "sol", 3)))
printf_channel_usage();
else
{
uint8_t ch = 0xe;
if (argc == 4)
ch = (uint8_t)strtol(argv[3], NULL, 0);
retval = ipmi_get_channel_cipher_suites(intf,
argv[1], // all | supported
argv[2], // ipmi | sol
ch);
}
}
else else
{ {
printf("Invalid CHANNEL command: %s\n", argv[0]); printf("Invalid CHANNEL command: %s\n", argv[0]);

View File

@ -89,8 +89,6 @@ ipmi_chassis_power_control(struct ipmi_intf * intf, uint8_t ctl)
struct ipmi_rs * rsp; struct ipmi_rs * rsp;
struct ipmi_rq req; struct ipmi_rq req;
ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN);
memset(&req, 0, sizeof(req)); memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_CHASSIS; req.msg.netfn = IPMI_NETFN_CHASSIS;
req.msg.cmd = 0x2; req.msg.cmd = 0x2;
@ -130,8 +128,6 @@ ipmi_chassis_identify(struct ipmi_intf * intf, char * arg)
uint8_t force_on; uint8_t force_on;
} identify_data; } identify_data;
ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN);
memset(&req, 0, sizeof(req)); memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_CHASSIS; req.msg.netfn = IPMI_NETFN_CHASSIS;
req.msg.cmd = 0x4; req.msg.cmd = 0x4;
@ -213,6 +209,8 @@ ipmi_chassis_poh(struct ipmi_intf * intf)
printf("POH Counter : %li hours total (%li days, %li hours)\n", printf("POH Counter : %li hours total (%li days, %li hours)\n",
(long)count, (long)(count / 24), (long)(count % 24)); (long)count, (long)(count / 24), (long)(count % 24));
return 0;
} }
static int static int
@ -365,8 +363,6 @@ ipmi_chassis_set_bootparam(struct ipmi_intf * intf, uint8_t param, uint8_t * dat
struct ipmi_rq req; struct ipmi_rq req;
uint8_t msg_data[16]; uint8_t msg_data[16];
ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN);
memset(msg_data, 0, 16); memset(msg_data, 0, 16);
msg_data[0] = param & 0x7f; msg_data[0] = param & 0x7f;
memcpy(msg_data+1, data, len); memcpy(msg_data+1, data, len);
@ -388,7 +384,7 @@ ipmi_chassis_set_bootparam(struct ipmi_intf * intf, uint8_t param, uint8_t * dat
return -1; 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; return 0;
} }
@ -435,41 +431,55 @@ ipmi_chassis_get_bootparam(struct ipmi_intf * intf, char * arg)
} }
static int static int
ipmi_chassis_set_bootflag(struct ipmi_intf * intf, char * arg) ipmi_chassis_set_bootdev(struct ipmi_intf * intf, char * arg)
{ {
uint8_t flags[5]; uint8_t flags[5];
int rc = 0; int rc = 0;
ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN);
if (arg == NULL) { if (arg == NULL) {
lprintf(LOG_ERR, "No bootflag argument supplied"); lprintf(LOG_ERR, "No argument supplied");
return -1; return -1;
} }
if (strncmp(arg, "force_pxe", 9) == 0) memset(flags, 0, 5);
flags[0] = 0x01;
flags[1] = 0x01;
rc = ipmi_chassis_set_bootparam(intf, 4, flags, 2);
if (rc < 0)
return -1;
memset(flags, 0, 5);
if (strncmp(arg, "pxe", 3) == 0 ||
strncmp(arg, "force_pxe", 9) == 0)
flags[1] = 0x04; 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; 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; 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; 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; flags[1] = 0x3c;
else if (strncmp(arg, "bios", 4) == 0 ||
strncmp(arg, "force_bios", 10) == 0)
flags[1] = 0x18;
else { else {
lprintf(LOG_ERR, "Invalid bootflag: %s", arg); lprintf(LOG_ERR, "Invalid argument: %s", arg);
return -1; return -1;
} }
flags[0] = 0x80; /* set flag valid bit */ /* set flag valid bit */
flags[0] = 0x80;
rc = ipmi_chassis_set_bootparam(intf, 5, flags, 5); rc = ipmi_chassis_set_bootparam(intf, 5, flags, 5);
if (rc == 0)
if (rc < 0) { printf("Set Boot Device to %s\n", arg);
flags[0] = 0x08; /* don't automatically clear boot flag valid bit in 60 seconds */
rc = ipmi_chassis_set_bootparam(intf, 3, flags, 1);
}
return rc; return rc;
} }
@ -479,8 +489,6 @@ ipmi_chassis_power_policy(struct ipmi_intf * intf, uint8_t policy)
struct ipmi_rs * rsp; struct ipmi_rs * rsp;
struct ipmi_rq req; struct ipmi_rq req;
ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN);
memset(&req, 0, sizeof(req)); memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_CHASSIS; req.msg.netfn = IPMI_NETFN_CHASSIS;
req.msg.cmd = 0x6; req.msg.cmd = 0x6;
@ -533,7 +541,7 @@ ipmi_chassis_main(struct ipmi_intf * intf, int argc, char ** argv)
int rc = 0; int rc = 0;
if ((argc == 0) || (strncmp(argv[0], "help", 4) == 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");
} }
else if (strncmp(argv[0], "status", 6) == 0) { else if (strncmp(argv[0], "status", 6) == 0) {
rc = ipmi_chassis_status(intf); rc = ipmi_chassis_status(intf);
@ -611,9 +619,16 @@ ipmi_chassis_main(struct ipmi_intf * intf, int argc, char ** argv)
rc = ipmi_chassis_power_policy(intf, ctl); 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)) { 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 { else {
if (strncmp(argv[1], "get", 3) == 0) { if (strncmp(argv[1], "get", 3) == 0) {
@ -624,7 +639,7 @@ ipmi_chassis_main(struct ipmi_intf * intf, int argc, char ** argv)
lprintf(LOG_NOTICE, "bootparam set <option> [value ...]"); lprintf(LOG_NOTICE, "bootparam set <option> [value ...]");
} else { } else {
if (strncmp(argv[2], "bootflag", 8) == 0) if (strncmp(argv[2], "bootflag", 8) == 0)
rc = ipmi_chassis_set_bootflag(intf, argv[3]); rc = ipmi_chassis_set_bootdev(intf, argv[3]);
else else
lprintf(LOG_NOTICE, "bootparam set <option> [value ...]"); lprintf(LOG_NOTICE, "bootparam set <option> [value ...]");
} }
@ -633,6 +648,19 @@ ipmi_chassis_main(struct ipmi_intf * intf, int argc, char ** argv)
lprintf(LOG_NOTICE, "bootparam get|set <option> [value ...]"); 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>");
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 {
rc = ipmi_chassis_set_bootdev(intf, argv[1]);
}
}
else { else {
lprintf(LOG_ERR, "Invalid Chassis command: %s", argv[0]); lprintf(LOG_ERR, "Invalid Chassis command: %s", argv[0]);
return -1; return -1;

View File

@ -63,8 +63,6 @@ ipmi_send_platform_event(struct ipmi_intf * intf, int num)
uint8_t chmed; uint8_t chmed;
int p = 0; int p = 0;
ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN);
memset(&req, 0, sizeof(req)); memset(&req, 0, sizeof(req));
memset(rqdata, 0, 8); memset(rqdata, 0, 8);
@ -150,9 +148,6 @@ ipmi_event_fromfile(struct ipmi_intf * intf, char * file)
if (file == NULL) if (file == NULL)
return -1; return -1;
/* must be admin privilege to do this */
ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN);
memset(rqdata, 0, 8); memset(rqdata, 0, 8);
/* setup Platform Event Message command */ /* setup Platform Event Message command */
@ -173,7 +168,7 @@ ipmi_event_fromfile(struct ipmi_intf * intf, char * file)
if (fp == NULL) if (fp == NULL)
return -1; return -1;
while (feof(fp) != 0) { while (feof(fp) == 0) {
if (fgets(buf, 1024, fp) == NULL) if (fgets(buf, 1024, fp) == NULL)
continue; continue;

View File

@ -59,7 +59,7 @@ extern int ipmi_spd_print(struct ipmi_intf * intf, uint8_t id);
* returns pointer to FRU area string * returns pointer to FRU area string
*/ */
static char * static char *
get_fru_area_str(uint8_t * data, int * offset) get_fru_area_str(uint8_t * data, uint32_t * offset)
{ {
static const char bcd_plus[] = "0123456789 -.:,_"; static const char bcd_plus[] = "0123456789 -.:,_";
char * str; char * str;
@ -96,7 +96,10 @@ get_fru_area_str(uint8_t * data, int * offset)
} }
if (size < 1) if (size < 1)
{
*offset = off;
return NULL; return NULL;
}
str = malloc(size+1); str = malloc(size+1);
if (str == NULL) if (str == NULL)
return NULL; return NULL;
@ -351,6 +354,13 @@ fru_area_print_board(struct ipmi_intf * intf, struct fru_info * fru,
i++; /* skip fru board language */ i++; /* skip fru board language */
i += 3; /* skip mfg. date time */ i += 3; /* skip mfg. date time */
fru_area = get_fru_area_str(fru_data, &i);
if (fru_area != NULL && strlen(fru_area) > 0) {
printf(" Board Mfg : %s\n", fru_area);
free(fru_area);
}
fru_area = get_fru_area_str(fru_data, &i); fru_area = get_fru_area_str(fru_data, &i);
if (fru_area != NULL && strlen(fru_area) > 0) { if (fru_area != NULL && strlen(fru_area) > 0) {
printf(" Board Product : %s\n", fru_area); printf(" Board Product : %s\n", fru_area);
@ -934,7 +944,8 @@ ipmi_fru_main(struct ipmi_intf * intf, int argc, char ** argv)
rc = ipmi_fru_print_all(intf); rc = ipmi_fru_print_all(intf);
else if (strncmp(argv[0], "help", 4) == 0) else if (strncmp(argv[0], "help", 4) == 0)
lprintf(LOG_ERR, "FRU Commands: print"); lprintf(LOG_ERR, "FRU Commands: print");
else if (strncmp(argv[0], "print", 5) == 0) else if (strncmp(argv[0], "print", 5) == 0 ||
strncmp(argv[0], "list", 4) == 0)
rc = ipmi_fru_print_all(intf); rc = ipmi_fru_print_all(intf);
else { else {
lprintf(LOG_ERR, "Invalid FRU command: %s", argv[0]); lprintf(LOG_ERR, "Invalid FRU command: %s", argv[0]);

195
ipmitool/lib/ipmi_isol.c Normal file
View 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;
}

View File

@ -37,6 +37,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <strings.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <arpa/inet.h> #include <arpa/inet.h>
@ -59,6 +60,18 @@
extern int verbose; extern int verbose;
/* get_lan_param - Query BMC for LAN parameter data
*
* return pointer to lan_param if successful
* if parameter not supported then
* return pointer to lan_param with
* lan_param->data == NULL and lan_param->data_len == 0
* return NULL on error
*
* @intf: ipmi interface handle
* @chan: ipmi channel
* @param: lan parameter id
*/
static struct lan_param * static struct lan_param *
get_lan_param(struct ipmi_intf * intf, uint8_t chan, int param) get_lan_param(struct ipmi_intf * intf, uint8_t chan, int param)
{ {
@ -87,8 +100,16 @@ get_lan_param(struct ipmi_intf * intf, uint8_t chan, int param)
lprintf(LOG_INFO, "Get LAN Parameter command failed"); lprintf(LOG_INFO, "Get LAN Parameter command failed");
return NULL; return NULL;
} }
if (rsp->ccode == 0x80) {
/* parameter not supported
* return lan_param without data
*/
p->data = NULL;
p->data_len = 0;
return p;
}
if (rsp->ccode > 0) { if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Get LAN Parameter command failed: %s", lprintf(LOG_INFO, "Get LAN Parameter command failed: %s",
val2str(rsp->ccode, completion_code_vals)); val2str(rsp->ccode, completion_code_vals));
return NULL; return NULL;
} }
@ -330,6 +351,8 @@ lan_set_arp_interval(struct ipmi_intf * intf,
lp = get_lan_param(intf, chan, IPMI_LANP_GRAT_ARP); lp = get_lan_param(intf, chan, IPMI_LANP_GRAT_ARP);
if (lp == NULL) if (lp == NULL)
return -1; return -1;
if (lp->data == NULL)
return -1;
if (ival != 0) { if (ival != 0) {
interval = ((uint8_t)atoi(ival) * 2) - 1; interval = ((uint8_t)atoi(ival) * 2) - 1;
@ -354,6 +377,8 @@ lan_set_arp_generate(struct ipmi_intf * intf,
lp = get_lan_param(intf, chan, IPMI_LANP_BMC_ARP); lp = get_lan_param(intf, chan, IPMI_LANP_BMC_ARP);
if (lp == NULL) if (lp == NULL)
return -1; return -1;
if (lp->data == NULL)
return -1;
data = lp->data[0]; data = lp->data[0];
/* set arp generate bitflag */ /* set arp generate bitflag */
@ -376,6 +401,8 @@ lan_set_arp_respond(struct ipmi_intf * intf,
lp = get_lan_param(intf, chan, IPMI_LANP_BMC_ARP); lp = get_lan_param(intf, chan, IPMI_LANP_BMC_ARP);
if (lp == NULL) if (lp == NULL)
return -1; return -1;
if (lp->data == NULL)
return -1;
data = lp->data[0]; data = lp->data[0];
/* set arp response bitflag */ /* set arp response bitflag */
@ -388,6 +415,34 @@ lan_set_arp_respond(struct ipmi_intf * intf,
return set_lan_param(intf, chan, IPMI_LANP_BMC_ARP, &data, 1); return set_lan_param(intf, chan, IPMI_LANP_BMC_ARP, &data, 1);
} }
static char priv_level_to_char(unsigned char priv_level)
{
char ret = 'X';
switch (priv_level)
{
case IPMI_SESSION_PRIV_CALLBACK:
ret = 'c';
break;
case IPMI_SESSION_PRIV_USER:
ret = 'u';
break;
case IPMI_SESSION_PRIV_OPERATOR:
ret = 'o';
break;
case IPMI_SESSION_PRIV_ADMIN:
ret = 'a';
break;
case IPMI_SESSION_PRIV_OEM:
ret = 'O';
break;
}
return ret;
}
static int static int
ipmi_lan_print(struct ipmi_intf * intf, uint8_t chan) ipmi_lan_print(struct ipmi_intf * intf, uint8_t chan)
{ {
@ -410,7 +465,9 @@ ipmi_lan_print(struct ipmi_intf * intf, uint8_t chan)
} }
p = get_lan_param(intf, chan, IPMI_LANP_SET_IN_PROGRESS); p = get_lan_param(intf, chan, IPMI_LANP_SET_IN_PROGRESS);
if (p) { if (p == NULL)
return -1;
if (p->data != NULL) {
printf("%-24s: ", p->desc); printf("%-24s: ", p->desc);
p->data[0] &= 3; p->data[0] &= 3;
switch (p->data[0]) { switch (p->data[0]) {
@ -430,11 +487,11 @@ ipmi_lan_print(struct ipmi_intf * intf, uint8_t chan)
printf("Unknown\n"); printf("Unknown\n");
} }
} }
else
rc = -1;
p = get_lan_param(intf, chan, IPMI_LANP_AUTH_TYPE); p = get_lan_param(intf, chan, IPMI_LANP_AUTH_TYPE);
if (p) { if (p == NULL)
return -1;
if (p->data != NULL) {
printf("%-24s: %s%s%s%s%s\n", p->desc, printf("%-24s: %s%s%s%s%s\n", p->desc,
(p->data[0] & 1<<IPMI_SESSION_AUTHTYPE_NONE) ? "NONE " : "", (p->data[0] & 1<<IPMI_SESSION_AUTHTYPE_NONE) ? "NONE " : "",
(p->data[0] & 1<<IPMI_SESSION_AUTHTYPE_MD2) ? "MD2 " : "", (p->data[0] & 1<<IPMI_SESSION_AUTHTYPE_MD2) ? "MD2 " : "",
@ -442,11 +499,11 @@ ipmi_lan_print(struct ipmi_intf * intf, uint8_t chan)
(p->data[0] & 1<<IPMI_SESSION_AUTHTYPE_PASSWORD) ? "PASSWORD " : "", (p->data[0] & 1<<IPMI_SESSION_AUTHTYPE_PASSWORD) ? "PASSWORD " : "",
(p->data[0] & 1<<IPMI_SESSION_AUTHTYPE_OEM) ? "OEM " : ""); (p->data[0] & 1<<IPMI_SESSION_AUTHTYPE_OEM) ? "OEM " : "");
} }
else
rc = -1;
p = get_lan_param(intf, chan, IPMI_LANP_AUTH_TYPE_ENABLE); p = get_lan_param(intf, chan, IPMI_LANP_AUTH_TYPE_ENABLE);
if (p) { if (p == NULL)
return -1;
if (p->data != NULL) {
printf("%-24s: Callback : %s%s%s%s%s\n", p->desc, printf("%-24s: Callback : %s%s%s%s%s\n", p->desc,
(p->data[0] & 1<<IPMI_SESSION_AUTHTYPE_NONE) ? "NONE " : "", (p->data[0] & 1<<IPMI_SESSION_AUTHTYPE_NONE) ? "NONE " : "",
(p->data[0] & 1<<IPMI_SESSION_AUTHTYPE_MD2) ? "MD2 " : "", (p->data[0] & 1<<IPMI_SESSION_AUTHTYPE_MD2) ? "MD2 " : "",
@ -478,11 +535,11 @@ ipmi_lan_print(struct ipmi_intf * intf, uint8_t chan)
(p->data[4] & 1<<IPMI_SESSION_AUTHTYPE_PASSWORD) ? "PASSWORD " : "", (p->data[4] & 1<<IPMI_SESSION_AUTHTYPE_PASSWORD) ? "PASSWORD " : "",
(p->data[4] & 1<<IPMI_SESSION_AUTHTYPE_OEM) ? "OEM " : ""); (p->data[4] & 1<<IPMI_SESSION_AUTHTYPE_OEM) ? "OEM " : "");
} }
else
rc = -1;
p = get_lan_param(intf, chan, IPMI_LANP_IP_ADDR_SRC); p = get_lan_param(intf, chan, IPMI_LANP_IP_ADDR_SRC);
if (p) { if (p == NULL)
return -1;
if (p->data != NULL) {
printf("%-24s: ", p->desc); printf("%-24s: ", p->desc);
p->data[0] &= 0xf; p->data[0] &= 0xf;
switch (p->data[0]) { switch (p->data[0]) {
@ -503,84 +560,154 @@ ipmi_lan_print(struct ipmi_intf * intf, uint8_t chan)
break; break;
} }
} }
else
rc = -1;
p = get_lan_param(intf, chan, IPMI_LANP_IP_ADDR); p = get_lan_param(intf, chan, IPMI_LANP_IP_ADDR);
if (p) if (p == NULL)
return -1;
if (p->data != NULL)
printf("%-24s: %d.%d.%d.%d\n", p->desc, printf("%-24s: %d.%d.%d.%d\n", p->desc,
p->data[0], p->data[1], p->data[2], p->data[3]); p->data[0], p->data[1], p->data[2], p->data[3]);
else
rc = -1;
p = get_lan_param(intf, chan, IPMI_LANP_SUBNET_MASK); p = get_lan_param(intf, chan, IPMI_LANP_SUBNET_MASK);
if (p) if (p == NULL)
return -1;
if (p->data != NULL)
printf("%-24s: %d.%d.%d.%d\n", p->desc, printf("%-24s: %d.%d.%d.%d\n", p->desc,
p->data[0], p->data[1], p->data[2], p->data[3]); p->data[0], p->data[1], p->data[2], p->data[3]);
else
rc = -1;
p = get_lan_param(intf, chan, IPMI_LANP_MAC_ADDR); p = get_lan_param(intf, chan, IPMI_LANP_MAC_ADDR);
if (p) if (p == NULL)
return -1;
if (p->data != NULL)
printf("%-24s: %02x:%02x:%02x:%02x:%02x:%02x\n", p->desc, printf("%-24s: %02x:%02x:%02x:%02x:%02x:%02x\n", p->desc,
p->data[0], p->data[1], p->data[2], p->data[3], p->data[4], p->data[5]); p->data[0], p->data[1], p->data[2], p->data[3], p->data[4], p->data[5]);
else
rc = -1;
p = get_lan_param(intf, chan, IPMI_LANP_SNMP_STRING); p = get_lan_param(intf, chan, IPMI_LANP_SNMP_STRING);
if (p) if (p == NULL)
return -1;
if (p->data != NULL)
printf("%-24s: %s\n", p->desc, p->data); printf("%-24s: %s\n", p->desc, p->data);
else
rc = -1;
p = get_lan_param(intf, chan, IPMI_LANP_IP_HEADER); p = get_lan_param(intf, chan, IPMI_LANP_IP_HEADER);
if (p) if (p == NULL)
return -1;
if (p->data != NULL)
printf("%-24s: TTL=0x%02x Flags=0x%02x Precedence=0x%02x TOS=0x%02x\n", printf("%-24s: TTL=0x%02x Flags=0x%02x Precedence=0x%02x TOS=0x%02x\n",
p->desc, p->data[0], p->data[1] & 0xe0, p->data[2] & 0xe0, p->data[2] & 0x1e); p->desc, p->data[0], p->data[1] & 0xe0, p->data[2] & 0xe0, p->data[2] & 0x1e);
else
rc = -1;
p = get_lan_param(intf, chan, IPMI_LANP_BMC_ARP); p = get_lan_param(intf, chan, IPMI_LANP_BMC_ARP);
if (p) if (p == NULL)
return -1;
if (p->data != NULL)
printf("%-24s: ARP Responses %sabled, Gratuitous ARP %sabled\n", p->desc, printf("%-24s: ARP Responses %sabled, Gratuitous ARP %sabled\n", p->desc,
(p->data[0] & 2) ? "En" : "Dis", (p->data[0] & 1) ? "En" : "Dis"); (p->data[0] & 2) ? "En" : "Dis", (p->data[0] & 1) ? "En" : "Dis");
else
rc = -1;
p = get_lan_param(intf, chan, IPMI_LANP_GRAT_ARP); p = get_lan_param(intf, chan, IPMI_LANP_GRAT_ARP);
if (p) { if (p == NULL)
return -1;
if (p->data != NULL)
printf("%-24s: %.1f seconds\n", p->desc, (float)((p->data[0] + 1) / 2)); printf("%-24s: %.1f seconds\n", p->desc, (float)((p->data[0] + 1) / 2));
}
else
rc = -1;
p = get_lan_param(intf, chan, IPMI_LANP_DEF_GATEWAY_IP); p = get_lan_param(intf, chan, IPMI_LANP_DEF_GATEWAY_IP);
if (p) if (p == NULL)
return -1;
if (p->data != NULL)
printf("%-24s: %d.%d.%d.%d\n", p->desc, printf("%-24s: %d.%d.%d.%d\n", p->desc,
p->data[0], p->data[1], p->data[2], p->data[3]); p->data[0], p->data[1], p->data[2], p->data[3]);
else
rc = -1;
p = get_lan_param(intf, chan, IPMI_LANP_DEF_GATEWAY_MAC); p = get_lan_param(intf, chan, IPMI_LANP_DEF_GATEWAY_MAC);
if (p) if (p == NULL)
return -1;
if (p->data != NULL)
printf("%-24s: %02x:%02x:%02x:%02x:%02x:%02x\n", p->desc, printf("%-24s: %02x:%02x:%02x:%02x:%02x:%02x\n", p->desc,
p->data[0], p->data[1], p->data[2], p->data[3], p->data[4], p->data[5]); p->data[0], p->data[1], p->data[2], p->data[3], p->data[4], p->data[5]);
else
rc = -1;
p = get_lan_param(intf, chan, IPMI_LANP_BAK_GATEWAY_IP); p = get_lan_param(intf, chan, IPMI_LANP_BAK_GATEWAY_IP);
if (p) if (p == NULL)
return -1;
if (p->data != NULL)
printf("%-24s: %d.%d.%d.%d\n", p->desc, printf("%-24s: %d.%d.%d.%d\n", p->desc,
p->data[0], p->data[1], p->data[2], p->data[3]); p->data[0], p->data[1], p->data[2], p->data[3]);
else
rc = -1;
p = get_lan_param(intf, chan, IPMI_LANP_BAK_GATEWAY_MAC); p = get_lan_param(intf, chan, IPMI_LANP_BAK_GATEWAY_MAC);
if (p) if (p == NULL)
return -1;
if (p->data != NULL)
printf("%-24s: %02x:%02x:%02x:%02x:%02x:%02x\n", p->desc, printf("%-24s: %02x:%02x:%02x:%02x:%02x:%02x\n", p->desc,
p->data[0], p->data[1], p->data[2], p->data[3], p->data[4], p->data[5]); p->data[0], p->data[1], p->data[2], p->data[3], p->data[4], p->data[5]);
/* Determine supported Cipher Suites -- Requires two calls */
p = get_lan_param(intf, chan, IPMI_LANP_RMCP_CIPHER_SUPPORT);
if (p == NULL)
return -1;
else else
rc = -1; {
unsigned char cipher_suite_count = p->data[0];
p = get_lan_param(intf, chan, IPMI_LANP_RMCP_CIPHERS);
if (p == NULL)
return -1;
printf("%-24s: ", p->desc);
if (cipher_suite_count == 0)
printf("None\n");
else
{
/* Now we're dangerous. There are only 15 fixed cipher
suite IDs, but the spec allows for 16 in the return data.*/
if ((p->data != NULL) && (p->data_len <= 16))
{
unsigned int i;
for (i = 0; (i < 16) && (i < cipher_suite_count); ++i)
{
printf("%s%d",
(i > 0? ",": ""),
p->data[i + 1]);
}
printf("\n");
}
}
}
/* RMCP+ Messaging Cipher Suite Privilege Levels */
/* These are the privilege levels for the 15 fixed cipher suites */
p = get_lan_param(intf, chan, IPMI_LANP_RMCP_PRIV_LEVELS);
if (p == NULL)
return -1;
if ((p->data != NULL) && (p->data_len == 9))
{
printf("%-24s: %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n", p->desc,
priv_level_to_char(p->data[1] & 0x0F),
priv_level_to_char(p->data[1] >> 4),
priv_level_to_char(p->data[2] & 0x0F),
priv_level_to_char(p->data[2] >> 4),
priv_level_to_char(p->data[3] & 0x0F),
priv_level_to_char(p->data[3] >> 4),
priv_level_to_char(p->data[4] & 0x0F),
priv_level_to_char(p->data[4] >> 4),
priv_level_to_char(p->data[5] & 0x0F),
priv_level_to_char(p->data[5] >> 4),
priv_level_to_char(p->data[6] & 0x0F),
priv_level_to_char(p->data[6] >> 4),
priv_level_to_char(p->data[7] & 0x0F),
priv_level_to_char(p->data[7] >> 4),
priv_level_to_char(p->data[8] & 0x0F));
/* Now print a legend */
printf("%-24s: %s\n", "", " X=Cipher Suite Unused");
printf("%-24s: %s\n", "", " c=CALLBACK");
printf("%-24s: %s\n", "", " u=USER");
printf("%-24s: %s\n", "", " o=OPERATOR");
printf("%-24s: %s\n", "", " a=ADMIN");
printf("%-24s: %s\n", "", " O=OEM");
}
else
printf("%-24s: Not Available\n", p->desc);
return rc; return rc;
} }
@ -600,6 +727,8 @@ ipmi_lan_set_auth(struct ipmi_intf * intf, uint8_t chan, char * level, char * ty
lp = get_lan_param(intf, chan, IPMI_LANP_AUTH_TYPE_ENABLE); lp = get_lan_param(intf, chan, IPMI_LANP_AUTH_TYPE_ENABLE);
if (lp == NULL) if (lp == NULL)
return -1; return -1;
if (lp->data == NULL)
return -1;
lprintf(LOG_DEBUG, "%-24s: callback=0x%02x user=0x%02x operator=0x%02x admin=0x%02x oem=0x%02x", lprintf(LOG_DEBUG, "%-24s: callback=0x%02x user=0x%02x operator=0x%02x admin=0x%02x oem=0x%02x",
lp->desc, lp->data[0], lp->data[1], lp->data[2], lp->data[3], lp->data[4]); lp->desc, lp->data[0], lp->data[1], lp->data[2], lp->data[3], lp->data[4]);
@ -607,34 +736,41 @@ ipmi_lan_set_auth(struct ipmi_intf * intf, uint8_t chan, char * level, char * ty
memset(data, 0, 5); memset(data, 0, 5);
memcpy(data, lp->data, 5); memcpy(data, lp->data, 5);
for (p = types; p != NULL; p++) { p = types;
if (strncmp(p, "none", 4) == 0) while (p) {
if (strncasecmp(p, "none", 4) == 0)
authtype |= 1 << IPMI_SESSION_AUTHTYPE_NONE; authtype |= 1 << IPMI_SESSION_AUTHTYPE_NONE;
else if (strncmp(p, "md2", 3) == 0) else if (strncasecmp(p, "md2", 3) == 0)
authtype |= 1 << IPMI_SESSION_AUTHTYPE_MD2; authtype |= 1 << IPMI_SESSION_AUTHTYPE_MD2;
else if (strncmp(p, "md5", 3) == 0) else if (strncasecmp(p, "md5", 3) == 0)
authtype |= 1 << IPMI_SESSION_AUTHTYPE_MD5; authtype |= 1 << IPMI_SESSION_AUTHTYPE_MD5;
else if (strncmp(p, "key", 3) == 0) else if ((strncasecmp(p, "password", 8) == 0) ||
(strncasecmp(p, "key", 3) == 0))
authtype |= 1 << IPMI_SESSION_AUTHTYPE_KEY; authtype |= 1 << IPMI_SESSION_AUTHTYPE_KEY;
else if (strncmp(p, "oem", 3) == 0) else if (strncasecmp(p, "oem", 3) == 0)
authtype |= 1 << IPMI_SESSION_AUTHTYPE_OEM; authtype |= 1 << IPMI_SESSION_AUTHTYPE_OEM;
else else
lprintf(LOG_WARNING, "Invalid authentication type: %s", p); lprintf(LOG_WARNING, "Invalid authentication type: %s", p);
p = strchr(p, ','); p = strchr(p, ',');
if (p)
p++;
} }
for (p = level; p != NULL; p++) { p = level;
if (strncmp(p, "callback", 8) == 0) while (p) {
if (strncasecmp(p, "callback", 8) == 0)
data[0] = authtype; data[0] = authtype;
else if (strncmp(p, "user", 4) == 0) else if (strncasecmp(p, "user", 4) == 0)
data[1] = authtype; data[1] = authtype;
else if (strncmp(p, "operator", 8) == 0) else if (strncasecmp(p, "operator", 8) == 0)
data[2] = authtype; data[2] = authtype;
else if (strncmp(p, "admin", 5) == 0) else if (strncasecmp(p, "admin", 5) == 0)
data[3] = authtype; data[3] = authtype;
else else
lprintf(LOG_WARNING, "Invalid authentication level: %s", p); lprintf(LOG_WARNING, "Invalid authentication level: %s", p);
p = strchr(p, ','); p = strchr(p, ',');
if (p)
p++;
} }
if (verbose > 1) if (verbose > 1)
@ -681,6 +817,8 @@ ipmi_lan_set_password(struct ipmi_intf * intf,
ipmi_intf_session_set_password(intf, password); ipmi_intf_session_set_password(intf, password);
printf("Password %s for user %d\n", printf("Password %s for user %d\n",
(password == NULL) ? "cleared" : "set", userid); (password == NULL) ? "cleared" : "set", userid);
return 0;
} }
static int static int
@ -793,6 +931,85 @@ get_cmdline_macaddr(char * arg, uint8_t * buf)
return 0; return 0;
} }
static int
get_cmdline_cipher_suite_priv_data(char * arg, uint8_t * buf)
{
int i, ret = 0;
if (strlen(arg) != 15)
{
lprintf(LOG_ERR, "Invalid privilege specification length: %d",
strlen(arg));
return -1;
}
/*
* The first byte is reservered (0). The resst of the buffer is setup
* so that each nibble holds the maximum privilege level available for
* that cipher suite number. The number of nibbles (15) matches the number
* of fixed cipher suite IDs. This command documentation mentions 16 IDs
* but table 22-19 shows that there are only 15 (0-14).
*
* data 1 - reserved
* data 2 - maximum priv level for first (LSN) and second (MSN) ciphers
* data 3 - maximum priv level for third (LSN) and fourth (MSN) ciphers
* data 9 - maximum priv level for 15th (LSN) cipher.
*/
bzero(buf, 9);
for (i = 0; i < 15; ++i)
{
unsigned char priv_level;
switch (arg[i])
{
case 'X':
priv_level = IPMI_SESSION_PRIV_UNSPECIFIED; /* 0 */
break;
case 'c':
priv_level = IPMI_SESSION_PRIV_CALLBACK; /* 1 */
break;
case 'u':
priv_level = IPMI_SESSION_PRIV_USER; /* 2 */
break;
case 'o':
priv_level = IPMI_SESSION_PRIV_OPERATOR; /* 3 */
break;
case 'a':
priv_level = IPMI_SESSION_PRIV_ADMIN; /* 4 */
break;
case 'O':
priv_level = IPMI_SESSION_PRIV_OEM; /* 5 */
break;
default:
lprintf(LOG_ERR, "Invalid privilege specification char: %c",
arg[i]);
ret = -1;
break;
}
if (ret != 0)
break;
else
{
if ((i + 1) % 2)
{
// Odd number cipher suites will be in the LSN
buf[1 + (i / 2)] += priv_level;
}
else
{
// Even number cipher suites will be in the MSN
buf[1 + (i / 2)] += (priv_level << 4);
}
}
}
return ret;
}
static int static int
get_cmdline_ipaddr(char * arg, uint8_t * buf) get_cmdline_ipaddr(char * arg, uint8_t * buf)
{ {
@ -821,18 +1038,26 @@ static void ipmi_lan_set_usage(void)
lprintf(LOG_NOTICE, " bakgw macaddr <x:x:x:x:x:x> Set backup gateway MAC address"); lprintf(LOG_NOTICE, " bakgw macaddr <x:x:x:x:x:x> Set backup gateway MAC address");
lprintf(LOG_NOTICE, " password <password> Set session password for this channel"); lprintf(LOG_NOTICE, " password <password> Set session password for this channel");
lprintf(LOG_NOTICE, " snmp <community string> Set SNMP public community string"); lprintf(LOG_NOTICE, " snmp <community string> Set SNMP public community string");
lprintf(LOG_NOTICE, " user Enable default user for this channel");
lprintf(LOG_NOTICE, " access <on|off> Enable or disable access to this channel"); lprintf(LOG_NOTICE, " access <on|off> Enable or disable access to this channel");
lprintf(LOG_NOTICE, " arp response <on|off> Enable or disable BMC ARP responding"); lprintf(LOG_NOTICE, " arp response <on|off> Enable or disable BMC ARP responding");
lprintf(LOG_NOTICE, " arp generate <on|off> Enable or disable BMC gratuitous ARP generation"); lprintf(LOG_NOTICE, " arp generate <on|off> Enable or disable BMC gratuitous ARP generation");
lprintf(LOG_NOTICE, " arp interval <seconds> Set gratuitous ARP generation interval"); lprintf(LOG_NOTICE, " arp interval <seconds> Set gratuitous ARP generation interval");
lprintf(LOG_NOTICE, " auth <level> <type,..> Set channel authentication types"); lprintf(LOG_NOTICE, " auth <level> <type,..> Set channel authentication types");
lprintf(LOG_NOTICE, " level = callback, user, operator, admin"); lprintf(LOG_NOTICE, " level = CALLBACK, USER, OPERATOR, ADMIN");
lprintf(LOG_NOTICE, " type = none, md2, md5, key"); lprintf(LOG_NOTICE, " type = NONE, MD2, MD5, PASSWORD, OEM");
lprintf(LOG_NOTICE, " ipsrc <source> Set IP Address source"); lprintf(LOG_NOTICE, " ipsrc <source> Set IP Address source");
lprintf(LOG_NOTICE, " none = unspecified source"); lprintf(LOG_NOTICE, " none = unspecified source");
lprintf(LOG_NOTICE, " static = address manually configured to be static"); lprintf(LOG_NOTICE, " static = address manually configured to be static");
lprintf(LOG_NOTICE, " dhcp = address obtained by BMC running DHCP"); lprintf(LOG_NOTICE, " dhcp = address obtained by BMC running DHCP");
lprintf(LOG_NOTICE, " bios = address loaded by BIOS or system software\n"); lprintf(LOG_NOTICE, " bios = address loaded by BIOS or system software");
lprintf(LOG_NOTICE, " cipher_privs XXXXXXXXXXXXXXX Set RMCP+ cipher suite privilege levels");
lprintf(LOG_NOTICE, " X = Cipher Suite Unused");
lprintf(LOG_NOTICE, " c = CALLBACK");
lprintf(LOG_NOTICE, " u = USER");
lprintf(LOG_NOTICE, " o = OPERATOR");
lprintf(LOG_NOTICE, " a = ADMIN");
lprintf(LOG_NOTICE, " O = OEM\n");
} }
static int static int
@ -934,9 +1159,9 @@ ipmi_lan_set(struct ipmi_intf * intf, int argc, char ** argv)
if (argc < 3 || (strncmp(argv[2], "help", 4) == 0)) { if (argc < 3 || (strncmp(argv[2], "help", 4) == 0)) {
lprintf(LOG_NOTICE, lprintf(LOG_NOTICE,
"lan set <channel> auth <level> <type,type,...>\n" "lan set <channel> auth <level> <type,type,...>\n"
" level = callback, user, operator, admin\n" " level = CALLBACK, USER, OPERATOR, ADMIN\n"
" types = none, md2, md5, key, oem\n" " types = NONE, MD2, MD5, PASSWORD, OEM\n"
"example: lan set 7 auth admin key,md5\n"); "example: lan set 7 auth ADMIN PASSWORD,MD5\n");
} else { } else {
rc = ipmi_lan_set_auth(intf, chan, argv[2], argv[3]); rc = ipmi_lan_set_auth(intf, chan, argv[2], argv[3]);
} }
@ -1050,8 +1275,32 @@ ipmi_lan_set(struct ipmi_intf * intf, int argc, char ** argv)
rc = set_lan_param(intf, chan, IPMI_LANP_BAK_GATEWAY_MAC, data, 6); rc = set_lan_param(intf, chan, IPMI_LANP_BAK_GATEWAY_MAC, data, 6);
} }
} }
/* RMCP+ cipher suite privilege levels */
else if (strncmp(argv[1], "cipher_privs", 12) == 0)
{
if ((argc != 3) ||
(strncmp(argv[2], "help", 4) == 0) ||
get_cmdline_cipher_suite_priv_data(argv[2], data))
{
lprintf(LOG_NOTICE, "lan set <channel> cipher_privs XXXXXXXXXXXXXXX");
lprintf(LOG_NOTICE, " X = Cipher Suite Unused");
lprintf(LOG_NOTICE, " c = CALLBACK");
lprintf(LOG_NOTICE, " u = USER");
lprintf(LOG_NOTICE, " o = OPERATOR");
lprintf(LOG_NOTICE, " a = ADMIN");
lprintf(LOG_NOTICE, " O = OEM\n");
}
else
{
rc = set_lan_param(intf, chan, IPMI_LANP_RMCP_PRIV_LEVELS, data, 9);
}
}
return rc;
} }
int int
ipmi_lanp_main(struct ipmi_intf * intf, int argc, char ** argv) ipmi_lanp_main(struct ipmi_intf * intf, int argc, char ** argv)
{ {
@ -1062,8 +1311,6 @@ ipmi_lanp_main(struct ipmi_intf * intf, int argc, char ** argv)
return -1; return -1;
} }
/* all the lan parameters commands need admin level */
ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN);
if ((strncmp(argv[0], "printconf", 9) == 0) || if ((strncmp(argv[0], "printconf", 9) == 0) ||
(strncmp(argv[0], "print", 5) == 0)) { (strncmp(argv[0], "print", 5) == 0)) {

View File

@ -219,8 +219,6 @@ ipmi_mc_set_enables(struct ipmi_intf * intf, int argc, char ** argv)
uint8_t en; uint8_t en;
int i; int i;
ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN);
if (argc < 1 || strncmp(argv[0], "help", 4) == 0) { if (argc < 1 || strncmp(argv[0], "help", 4) == 0) {
printf_mc_usage(); printf_mc_usage();
return 0; return 0;
@ -370,6 +368,39 @@ ipmi_mc_get_deviceid(struct ipmi_intf * intf)
return 0; return 0;
} }
/* 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;
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;
}
printf("System GUID: %s\n", buf2str(rsp->data, rsp->data_len));
return 0;
}
/* ipmi_mc_main - top-level handler for MC functions /* ipmi_mc_main - top-level handler for MC functions
* *
* @intf: ipmi interface * @intf: ipmi interface
@ -404,6 +435,9 @@ ipmi_mc_main(struct ipmi_intf * intf, int argc, char ** argv)
else if (strncmp(argv[0], "info", 4) == 0) { else if (strncmp(argv[0], "info", 4) == 0) {
rc = ipmi_mc_get_deviceid(intf); 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) { else if (strncmp(argv[0], "getenables", 10) == 0) {
rc = ipmi_mc_get_enables(intf); rc = ipmi_mc_get_enables(intf);
} }

View File

@ -45,13 +45,18 @@ static int ipmi_oem_supermicro(struct ipmi_intf * intf);
static struct ipmi_oem_handle ipmi_oem_list[] = { static struct ipmi_oem_handle ipmi_oem_list[] = {
{ {
name: "supermicro", name: "supermicro",
desc: "Supermicro BMC with OEM LAN authentication support", desc: "Supermicro IPMIv1.5 BMC with OEM LAN authentication support",
setup: ipmi_oem_supermicro, setup: ipmi_oem_supermicro,
}, },
{ {
name: "intelwv2", 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",
},
{ 0 }, { 0 },
}; };
@ -70,9 +75,7 @@ ipmi_oem_print(void)
{ {
struct ipmi_oem_handle * oem; struct ipmi_oem_handle * oem;
lprintf(LOG_NOTICE, "\nOEM Support:"); lprintf(LOG_NOTICE, "\nOEM Support:");
for (oem=ipmi_oem_list; oem->setup != NULL; oem++) { for (oem=ipmi_oem_list; oem->name != NULL && oem->desc != NULL; oem++) {
if (oem->name == NULL || oem->desc == NULL)
continue;
lprintf(LOG_NOTICE, "\t%-12s %s", oem->name, oem->desc); lprintf(LOG_NOTICE, "\t%-12s %s", oem->name, oem->desc);
} }
lprintf(LOG_NOTICE, ""); lprintf(LOG_NOTICE, "");
@ -90,6 +93,7 @@ int
ipmi_oem_setup(struct ipmi_intf * intf, char * oemtype) ipmi_oem_setup(struct ipmi_intf * intf, char * oemtype)
{ {
struct ipmi_oem_handle * oem; struct ipmi_oem_handle * oem;
int i;
int rc = 0; int rc = 0;
if (strncmp(oemtype, "help", 4) == 0 || if (strncmp(oemtype, "help", 4) == 0 ||
@ -99,7 +103,7 @@ ipmi_oem_setup(struct ipmi_intf * intf, char * oemtype)
return -1; 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) if (oem->name == NULL)
continue; continue;
if (strncmp(oemtype, oem->name, strlen(oem->name)) == 0) if (strncmp(oemtype, oem->name, strlen(oem->name)) == 0)

View File

@ -76,12 +76,6 @@ static const char * pef_flag_fmts[][3] = {
{"active", "in", ""}, {"active", "in", ""},
{"abled", "dis", "en"}, {"abled", "dis", "en"},
}; };
typedef enum {
P_TRUE,
P_SUPP,
P_ACTV,
P_ABLE,
} flg_e;
static const char * listitem[] = {" | %s", ",%s", "%s"}; static const char * listitem[] = {" | %s", ",%s", "%s"};
const char * const char *

View File

@ -51,12 +51,18 @@ ipmi_raw_main(struct ipmi_intf * intf, int argc, char ** argv)
struct ipmi_rq req; struct ipmi_rq req;
uint8_t netfn, cmd; uint8_t netfn, cmd;
int i; int i;
uint8_t data[32];
uint8_t data[256];
if (argc < 2 || strncmp(argv[0], "help", 4) == 0) { if (argc < 2 || strncmp(argv[0], "help", 4) == 0) {
lprintf(LOG_NOTICE, "RAW Commands: raw <netfn> <cmd> [data]"); lprintf(LOG_NOTICE, "RAW Commands: raw <netfn> <cmd> [data]");
return -1; return -1;
} }
else if (argc > sizeof(data))
{
lprintf(LOG_NOTICE, "Raw command input limit (256 bytes) exceeded");
return -1;
}
netfn = (uint8_t)strtol(argv[0], NULL, 0); netfn = (uint8_t)strtol(argv[0], NULL, 0);
cmd = (uint8_t)strtol(argv[1], NULL, 0); cmd = (uint8_t)strtol(argv[1], NULL, 0);
@ -88,8 +94,8 @@ ipmi_raw_main(struct ipmi_intf * intf, int argc, char ** argv)
} }
if (rsp->ccode > 0) { if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Unable to send RAW command " lprintf(LOG_ERR, "Unable to send RAW command "
"(netfn=0x%x cmd=0x%x): %s", "(netfn=0x%x cmd=0x%x rsp=0x%x): %s",
req.msg.netfn, req.msg.cmd, req.msg.netfn, req.msg.cmd, rsp->ccode,
val2str(rsp->ccode, completion_code_vals)); val2str(rsp->ccode, completion_code_vals));
return -1; return -1;
} }

View File

@ -35,8 +35,8 @@
*/ */
#include <string.h> #include <string.h>
#include <math.h>
#include <math.h>
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
#include <sys/types.h> #include <sys/types.h>
@ -56,7 +56,8 @@
#endif #endif
#define READING_UNAVAILABLE 0x20 #define READING_UNAVAILABLE 0x20
#define SCANNING_DISABLED 0x80 #define SCANNING_DISABLED 0x40
#define EVENTS_DISABLED 0x80
#define GET_SENSOR_READING 0x2d #define GET_SENSOR_READING 0x2d
#define GET_SENSOR_FACTORS 0x23 #define GET_SENSOR_FACTORS 0x23
@ -95,11 +96,12 @@ utos(uint32_t val, int bits)
* *
* returns floating-point sensor reading * returns floating-point sensor reading
*/ */
float double
sdr_convert_sensor_reading(struct sdr_record_full_sensor * sensor, sdr_convert_sensor_reading(struct sdr_record_full_sensor * sensor,
uint8_t val) uint8_t val)
{ {
int m, b, k1, k2; int m, b, k1, k2;
double result;
m = __TO_M(sensor->mtol); m = __TO_M(sensor->mtol);
b = __TO_B(sensor->bacc); b = __TO_B(sensor->bacc);
@ -109,18 +111,61 @@ sdr_convert_sensor_reading(struct sdr_record_full_sensor * sensor,
switch (sensor->unit.analog) switch (sensor->unit.analog)
{ {
case 0: case 0:
return (float)(((m * val) + result = (double)(((m * val) +
(b * pow(10, k1))) * pow(10, k2)); (b * pow(10, k1))) * pow(10, k2));
break;
case 1: case 1:
if (val & 0x80) val ++; if (val & 0x80) val ++;
/* Deliberately fall through to case 2. */ /* Deliberately fall through to case 2. */
case 2: case 2:
return (float)(((m * (int8_t)val) + result = (double)(((m * (int8_t)val) +
(b * pow(10, k1))) * pow(10, k2)); (b * pow(10, k1))) * pow(10, k2));
break;
default: default:
/* Oops! This isn't an analog sensor. */ /* Oops! This isn't an analog sensor. */
return 0.0; return 0.0;
} }
switch (sensor->linearization & 0x7f) {
default:
case SDR_SENSOR_L_LINEAR:
break;
case SDR_SENSOR_L_LN:
result = log(result);
break;
case SDR_SENSOR_L_LOG10:
result = log10(result);
break;
case SDR_SENSOR_L_LOG2:
result = (double)(log(result) / log(2.0));
break;
case SDR_SENSOR_L_E:
result = exp(result);
break;
case SDR_SENSOR_L_EXP10:
result = pow(10.0, result);
break;
case SDR_SENSOR_L_EXP2:
result = pow(2.0, result);
break;
case SDR_SENSOR_L_1_X:
result = pow(result, -1.0); /*1/x w/o exception*/
break;
case SDR_SENSOR_L_SQR:
result = pow(result, 2.0);
break;
case SDR_SENSOR_L_CUBE:
result = pow(result, 3.0);
break;
case SDR_SENSOR_L_SQRT:
result = sqrt(result);
break;
case SDR_SENSOR_L_CUBERT:
result = cbrt(result);
break;
}
return result;
} }
/* sdr_convert_sensor_value_to_raw - convert sensor reading back to raw /* sdr_convert_sensor_value_to_raw - convert sensor reading back to raw
@ -132,7 +177,7 @@ sdr_convert_sensor_reading(struct sdr_record_full_sensor * sensor,
*/ */
uint8_t uint8_t
sdr_convert_sensor_value_to_raw(struct sdr_record_full_sensor * sensor, sdr_convert_sensor_value_to_raw(struct sdr_record_full_sensor * sensor,
float val) double val)
{ {
int m, b, k1, k2; int m, b, k1, k2;
double result; double result;
@ -364,23 +409,22 @@ ipmi_sdr_print_sensor_full(struct ipmi_intf * intf,
{ {
char sval[16], unitstr[16], desc[17]; char sval[16], unitstr[16], desc[17];
int i=0, validread=1, do_unit=1; int i=0, validread=1, do_unit=1;
float val = 0.0; double val = 0.0;
struct ipmi_rs * rsp; struct ipmi_rs * rsp;
uint8_t min_reading, max_reading; uint8_t min_reading, max_reading;
if (sensor == NULL) if (sensor == NULL)
return -1; return -1;
/* only handles linear sensors (for now) */
if (sensor->linearization) {
lprintf(LOG_ERR, "Sensor #%02x is non-linear",
sensor->keys.sensor_num);
return -1;
}
memset(desc, 0, sizeof(desc)); memset(desc, 0, sizeof(desc));
memcpy(desc, sensor->id_string, 16); memcpy(desc, sensor->id_string, 16);
/* only handle linear sensors and linearized sensors (for now) */
if (sensor->linearization>=SDR_SENSOR_L_NONLINEAR) {
printf("sensor %s non-linear!\n", desc);
return -1;
}
/* get sensor reading */ /* get sensor reading */
rsp = ipmi_sdr_get_sensor_reading(intf, sensor->keys.sensor_num); rsp = ipmi_sdr_get_sensor_reading(intf, sensor->keys.sensor_num);
@ -407,7 +451,13 @@ ipmi_sdr_print_sensor_full(struct ipmi_intf * intf,
else if (!(rsp->data[1] & SCANNING_DISABLED)) { else if (!(rsp->data[1] & SCANNING_DISABLED)) {
/* Sensor Scanning Disabled /* Sensor Scanning Disabled
* not an error condition so return 0 */ * not an error condition so return 0 */
return 0; validread = 0;
if (rsp->data[0] != 0) {
/* we might still get a valid reading */
val = sdr_convert_sensor_reading(sensor, rsp->data[0]);
if (val != 0.0)
validread = 1;
}
} }
else if (rsp->data[0] != 0) { else if (rsp->data[0] != 0) {
/* convert RAW reading into units */ /* convert RAW reading into units */
@ -509,9 +559,10 @@ ipmi_sdr_print_sensor_full(struct ipmi_intf * intf,
i += snprintf(sval, sizeof(sval), "%.*f %s", i += snprintf(sval, sizeof(sval), "%.*f %s",
(val==(int)val) ? 0 : 2, val, (val==(int)val) ? 0 : 2, val,
do_unit ? unitstr : ""); do_unit ? unitstr : "");
else if (!(rsp->data[1] & SCANNING_DISABLED))
i += snprintf(sval, sizeof(sval), "disabled ");
else else
i += snprintf(sval, sizeof(sval), i += snprintf(sval, sizeof(sval), "no reading ");
"no reading ");
printf("%s", sval); printf("%s", sval);
@ -561,14 +612,16 @@ ipmi_sdr_print_sensor_full(struct ipmi_intf * intf,
printf(" Sensor Reading : "); printf(" Sensor Reading : ");
if (validread) { if (validread) {
uint16_t raw_tol = __TO_TOL(sensor->mtol); 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", printf("%.*f (+/- %.*f) %s\n",
(val==(int)val) ? 0 : 3, (val==(int)val) ? 0 : 3,
val, val,
(tol==(int)tol) ? 0 : 3, (tol==(int)tol) ? 0 : 3,
tol, tol,
unitstr); unitstr);
} else } else if (!(rsp->data[1] & SCANNING_DISABLED))
printf("Disabled\n");
else
printf("Not Present\n"); printf("Not Present\n");
printf(" Status : %s\n", printf(" Status : %s\n",
@ -592,7 +645,7 @@ ipmi_sdr_print_sensor_full(struct ipmi_intf * intf,
(sensor->unit.analog == 2 && sensor->sensor_min == 0x80)) (sensor->unit.analog == 2 && sensor->sensor_min == 0x80))
printf(" Minimum sensor range : Unspecified\n"); printf(" Minimum sensor range : Unspecified\n");
else else
printf(" Minimum sensor range : %.3f\n", (float)min_reading); printf(" Minimum sensor range : %.3f\n", (double)min_reading);
max_reading = (uint8_t)sdr_convert_sensor_reading( max_reading = (uint8_t)sdr_convert_sensor_reading(
sensor, sensor->sensor_max); sensor, sensor->sensor_max);
@ -601,7 +654,7 @@ ipmi_sdr_print_sensor_full(struct ipmi_intf * intf,
(sensor->unit.analog == 2 && sensor->sensor_max == 0x7f)) (sensor->unit.analog == 2 && sensor->sensor_max == 0x7f))
printf(" Maximum sensor range : Unspecified\n"); printf(" Maximum sensor range : Unspecified\n");
else else
printf(" Maximum sensor range : %.3f\n", (float)max_reading); printf(" Maximum sensor range : %.3f\n", (double)max_reading);
printf(" Event Message Control : "); printf(" Event Message Control : ");
switch (sensor->sensor.capabilities.event_msg) { switch (sensor->sensor.capabilities.event_msg) {
@ -2173,13 +2226,28 @@ ipmi_sdr_print_entity(struct ipmi_intf * intf, char * entitystr)
uint32_t id, instance; uint32_t id, instance;
int rc = 0; int rc = 0;
if (sscanf(entitystr, "%u.%u", &id, &instance) != 2) { if (entitystr == NULL) {
lprintf(LOG_ERR, "Invalid entity: %s", entitystr); lprintf(LOG_ERR, "No Entity ID supplied");
return -1; return -1;
} }
entity.id = (uint8_t)id; if (sscanf(entitystr, "%u.%u", &id, &instance) != 2) {
entity.instance = (uint8_t)instance; /* perhaps no instance was passed
* in which case we want all instances for this entity
* so set entity.instance = 0x7f to indicate this
*/
if (sscanf(entitystr, "%u", &id) != 1) {
lprintf(LOG_ERR, "Invalid entity: %s", entitystr);
return -1;
} else {
entity.id = id;
entity.instance = 0x7f;
}
} else {
entity.id = id;
entity.instance = instance;
}
list = ipmi_sdr_find_sdr_byentity(intf, &entity); list = ipmi_sdr_find_sdr_byentity(intf, &entity);
for (entry = list; entry != NULL; entry = entry->next) { for (entry = list; entry != NULL; entry = entry->next) {
@ -2219,6 +2287,11 @@ ipmi_sdr_main(struct ipmi_intf * intf, int argc, char ** argv)
lprintf(LOG_ERR, " mcloc Management Controller Locator Record"); lprintf(LOG_ERR, " mcloc Management Controller Locator Record");
lprintf(LOG_ERR, " fru FRU Locator Record"); lprintf(LOG_ERR, " fru FRU Locator Record");
lprintf(LOG_ERR, " info"); lprintf(LOG_ERR, " info");
lprintf(LOG_ERR, " Display information about the repository itself");
lprintf(LOG_ERR, " entity <id>[.<instance>]");
lprintf(LOG_ERR, " Display all sensors associated with an entity");
lprintf(LOG_ERR, " dump <file>");
lprintf(LOG_ERR, " Dump raw SDR data to a file");
} }
else if (strncmp(argv[0], "list", 4) == 0) { else if (strncmp(argv[0], "list", 4) == 0) {
if (argc <= 1) if (argc <= 1)

View File

@ -124,15 +124,24 @@ ipmi_get_event_desc(struct sel_event_record * rec, char ** desc)
((evt->data == ALL_OFFSETS_SPECIFIED) || ((evt->data == ALL_OFFSETS_SPECIFIED) ||
((rec->event_data[0] & DATA_BYTE2_SPECIFIED_MASK) && ((rec->event_data[0] & DATA_BYTE2_SPECIFIED_MASK) &&
(evt->data == rec->event_data[1])))) (evt->data == rec->event_data[1]))))
{ {
*desc = (char *)malloc(strlen(evt->desc) + 32); *desc = (char *)malloc(strlen(evt->desc) + 48);
if (*desc == NULL) { if (*desc == NULL) {
lprintf(LOG_ERR, "ipmitool: malloc failure"); lprintf(LOG_ERR, "ipmitool: malloc failure");
return; return;
} }
sprintf(*desc, "%s", evt->desc); sprintf(*desc, "%s", evt->desc);
if(rec->event_type==0x01)
{
//Append asserted/deasserted state for
//threshold events
sprintf(
*desc+strlen(*desc),
" - %s",
rec->event_dir?"deasserted":"asserted");
}
return; return;
} }
evt++; evt++;
} }
} }
@ -198,7 +207,7 @@ ipmi_sel_get_info(struct ipmi_intf * intf)
rsp->data[13] & 0x80 ? "true" : "false"); rsp->data[13] & 0x80 ? "true" : "false");
printf("Delete cmd : %ssupported\n", printf("Delete cmd : %ssupported\n",
rsp->data[13] & 0x8 ? "" : "un"); rsp->data[13] & 0x8 ? "" : "un");
printf("Parial add cmd : %ssupported\n", printf("Partial add cmd : %ssupported\n",
rsp->data[13] & 0x4 ? "" : "un"); rsp->data[13] & 0x4 ? "" : "un");
printf("Reserve cmd : %ssupported\n", printf("Reserve cmd : %ssupported\n",
rsp->data[13] & 0x2 ? "" : "un"); rsp->data[13] & 0x2 ? "" : "un");
@ -578,12 +587,13 @@ ipmi_sel_print_extended_entry_verbose(struct sel_event_record * evt, struct sdr_
} }
static int static int
ipmi_sel_list_entries(struct ipmi_intf * intf) ipmi_sel_list_entries(struct ipmi_intf * intf, int count)
{ {
struct ipmi_rs * rsp; struct ipmi_rs * rsp;
struct ipmi_rq req; struct ipmi_rq req;
uint16_t next_id = 0, curr_id = 0; uint16_t next_id = 0, curr_id = 0;
struct sel_event_record evt; struct sel_event_record evt;
int n=0;
memset(&req, 0, sizeof(req)); memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_STORAGE; req.msg.netfn = IPMI_NETFN_STORAGE;
@ -622,6 +632,21 @@ ipmi_sel_list_entries(struct ipmi_intf * intf)
return -1; return -1;
} }
if (count < 0) {
/** Show only the most recent 'count' records. */
int delta;
/* Get first record. */
next_id = ipmi_sel_get_std_entry(intf, 0, &evt);
delta = next_id - evt.record_id;
/* Get last record. */
next_id = ipmi_sel_get_std_entry(intf, 0xffff, &evt);
next_id = evt.record_id + count * delta + delta;
}
while (next_id != 0xffff) { while (next_id != 0xffff) {
curr_id = next_id; curr_id = next_id;
lprintf(LOG_DEBUG, "SEL Next ID: %04x", curr_id); lprintf(LOG_DEBUG, "SEL Next ID: %04x", curr_id);
@ -642,7 +667,13 @@ ipmi_sel_list_entries(struct ipmi_intf * intf)
ipmi_sel_print_std_entry_verbose(&evt); ipmi_sel_print_std_entry_verbose(&evt);
else else
ipmi_sel_print_std_entry(&evt); ipmi_sel_print_std_entry(&evt);
if (++n == count) {
break;
}
} }
return 0;
} }
static uint16_t static uint16_t
@ -785,8 +816,6 @@ ipmi_sel_clear(struct ipmi_intf * intf)
uint16_t reserve_id; uint16_t reserve_id;
uint8_t msg_data[6]; uint8_t msg_data[6];
ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN);
reserve_id = ipmi_sel_reserve(intf); reserve_id = ipmi_sel_reserve(intf);
if (reserve_id == 0) if (reserve_id == 0)
return -1; return -1;
@ -807,7 +836,7 @@ ipmi_sel_clear(struct ipmi_intf * intf)
rsp = intf->sendrecv(intf, &req); rsp = intf->sendrecv(intf, &req);
if (rsp == NULL) { if (rsp == NULL) {
lprintf(LOG_ERR, "Unable to clear SEL: %s"); lprintf(LOG_ERR, "Unable to clear SEL");
return -1; return -1;
} }
if (rsp->ccode > 0) { if (rsp->ccode > 0) {
@ -952,6 +981,17 @@ ipmi_sel_show_entry(struct ipmi_intf * intf, int argc, char ** argv)
return rc; return rc;
} }
static int make_int(const char *str, int *value)
{
char *tmp=NULL;
*value = strtol(str,&tmp,0);
if ( tmp-str != strlen(str) )
{
return -1;
}
return 0;
}
int ipmi_sel_main(struct ipmi_intf * intf, int argc, char ** argv) int ipmi_sel_main(struct ipmi_intf * intf, int argc, char ** argv)
{ {
int rc = 0; int rc = 0;
@ -962,8 +1002,43 @@ int ipmi_sel_main(struct ipmi_intf * intf, int argc, char ** argv)
lprintf(LOG_ERR, "SEL Commands: info clear delete list time"); lprintf(LOG_ERR, "SEL Commands: info clear delete list time");
else if (strncmp(argv[0], "info", 4) == 0) else if (strncmp(argv[0], "info", 4) == 0)
rc = ipmi_sel_get_info(intf); rc = ipmi_sel_get_info(intf);
else if (strncmp(argv[0], "list", 4) == 0) else if (strncmp(argv[0], "list", 4) == 0) {
rc = ipmi_sel_list_entries(intf); /*
* Usage:
* list - show all SEL entries
* list first <n> - show the first (oldest) <n> SEL entries
* list last <n> - show the last (newsest) <n> SEL entries
*/
int count = 0;
int sign = 1;
char *countstr = NULL;
if (argc == 3) {
countstr = argv[2];
if (strncmp(argv[1], "last", 4) == 0) {
sign = -1;
}
else if (strncmp(argv[1], "first", 6) != 0) {
lprintf(LOG_ERR, "Unknown sel list option");
return -1;
}
}
else if (argc == 2) {
countstr = argv[1];
}
if (countstr) {
if (make_int(countstr,&count) < 0) {
lprintf(LOG_ERR, "Numeric argument required; got '%s'",
countstr);
return -1;
}
}
count *= sign;
rc = ipmi_sel_list_entries(intf,count);
}
else if (strncmp(argv[0], "clear", 5) == 0) else if (strncmp(argv[0], "clear", 5) == 0)
rc = ipmi_sel_clear(intf); rc = ipmi_sel_clear(intf);
else if (strncmp(argv[0], "delete", 6) == 0) { else if (strncmp(argv[0], "delete", 6) == 0) {

View File

@ -182,23 +182,22 @@ ipmi_sensor_print_full_analog(struct ipmi_intf * intf,
{ {
char unitstr[16], id[17]; char unitstr[16], id[17];
int i=0, validread=1, thresh_available = 1; int i=0, validread=1, thresh_available = 1;
float val = 0.0; double val = 0.0;
struct ipmi_rs * rsp; struct ipmi_rs * rsp;
char * status = NULL; char * status = NULL;
if (sensor == NULL) if (sensor == NULL)
return -1; return -1;
/* only handle linear sensors (for now) */
if (sensor->linearization) {
lprintf(LOG_ERR, "Sensor #%02x is non-linear",
sensor->keys.sensor_num);
return -1;
}
memset(id, 0, sizeof(id)); memset(id, 0, sizeof(id));
memcpy(id, sensor->id_string, 16); 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;
}
/* /*
* Get current reading * Get current reading
*/ */
@ -315,7 +314,7 @@ ipmi_sensor_print_full_analog(struct ipmi_intf * intf,
printf(" Sensor Reading : "); printf(" Sensor Reading : ");
if (validread) { if (validread) {
uint16_t raw_tol = __TO_TOL(sensor->mtol); 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", printf("%.*f (+/- %.*f) %s\n",
(val==(int)val) ? 0 : 3, (val==(int)val) ? 0 : 3,
val, val,
@ -365,6 +364,8 @@ ipmi_sensor_print_full_analog(struct ipmi_intf * intf,
printf("\n"); printf("\n");
} }
} }
return 0;
} }
int int
@ -511,7 +512,7 @@ ipmi_sensor_set_threshold(struct ipmi_intf * intf, int argc, char ** argv)
{ {
char * id, * thresh; char * id, * thresh;
uint8_t settingMask; uint8_t settingMask;
float setting; double setting;
struct sdr_record_list * sdr; struct sdr_record_list * sdr;
struct ipmi_rs * rsp; struct ipmi_rs * rsp;
@ -530,11 +531,9 @@ ipmi_sensor_set_threshold(struct ipmi_intf * intf, int argc, char ** argv)
return 0; return 0;
} }
ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN);
id = argv[0]; id = argv[0];
thresh = argv[1]; thresh = argv[1];
setting = (float)atof(argv[2]); setting = (double)atof(argv[2]);
if (strncmp(thresh, "unr", 3) == 0) if (strncmp(thresh, "unr", 3) == 0)
settingMask = UPPER_NON_RECOV_SPECIFIED; settingMask = UPPER_NON_RECOV_SPECIFIED;
else if (strncmp(thresh, "ucr", 3) == 0) else if (strncmp(thresh, "ucr", 3) == 0)

View File

@ -97,11 +97,19 @@ print_session_info_csv(const struct get_session_info_rsp * session_info,
if (data_len == 18) if (data_len == 18)
{ {
/* We have 802.3 LAN data */ /* 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", printf(",%s",
inet_ntop(AF_INET, inet_ntop(AF_INET,
&(session_info->channel_data.lan_data.console_ip), &(session_info->channel_data.lan_data.console_ip),
buffer, buffer,
16)); 16));
#endif
printf(",%02x:%02x:%02x:%02x:%02x:%02x", printf(",%02x:%02x:%02x:%02x:%02x:%02x",
session_info->channel_data.lan_data.console_mac[0], 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", printf(",%d",
session_info->channel_data.modem_data.destination_selector); 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", printf(",%s",
inet_ntop(AF_INET, inet_ntop(AF_INET,
&(session_info->channel_data.modem_data.console_ip), &(session_info->channel_data.modem_data.console_ip),
buffer, buffer,
16)); 16));
#endif
if (data_len == 14) if (data_len == 14)
{ {
@ -185,11 +201,19 @@ print_session_info_verbose(const struct get_session_info_rsp * session_info,
if (data_len == 18) if (data_len == 18)
{ {
/* We have 802.3 LAN data */ /* 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", printf("console ip : %s\n",
inet_ntop(AF_INET, inet_ntop(AF_INET,
&(session_info->channel_data.lan_data.console_ip), &(session_info->channel_data.lan_data.console_ip),
buffer, buffer,
16)); 16));
#endif
printf("console mac : %02x:%02x:%02x:%02x:%02x:%02x\n", printf("console mac : %02x:%02x:%02x:%02x:%02x:%02x\n",
session_info->channel_data.lan_data.console_mac[0], 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", printf("Destination selector : %d\n",
session_info->channel_data.modem_data.destination_selector); 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", printf("console ip : %s\n",
inet_ntop(AF_INET, inet_ntop(AF_INET,
&(session_info->channel_data.modem_data.console_ip), &(session_info->channel_data.modem_data.console_ip),
buffer, buffer,
16)); 16));
#endif
if (data_len == 14) if (data_len == 14)
{ {
@ -317,7 +349,7 @@ ipmi_get_session_info(struct ipmi_intf * intf,
if (retval < 0) if (retval < 0)
{ {
if ((session_request_type == IPMI_SESSION_REQUEST_CURRENT) && 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 " lprintf(LOG_ERR, "It is likely that the channel in use "
"does not support sessions"); "does not support sessions");
} }

View File

@ -36,8 +36,10 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <strings.h>
#include <stdio.h> #include <stdio.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h>
#include <sys/select.h> #include <sys/select.h>
#include <sys/time.h> #include <sys/time.h>
#include <signal.h> #include <signal.h>
@ -67,6 +69,20 @@
#define SOL_ESCAPE_CHARACTER '~' #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 struct termios _saved_tio;
static int _in_raw_mode = 0; static int _in_raw_mode = 0;
@ -102,22 +118,33 @@ ipmi_get_sol_info(
data[3] = 0x00; /* block selector */ data[3] = 0x00; /* block selector */
rsp = intf->sendrecv(intf, &req); 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 * SOL enable
@ -129,22 +156,33 @@ ipmi_get_sol_info(
data[3] = 0x00; /* block selector */ data[3] = 0x00; /* block selector */
rsp = intf->sendrecv(intf, &req); 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 * SOL authentication
@ -156,24 +194,34 @@ ipmi_get_sol_info(
data[3] = 0x00; /* block selector */ data[3] = 0x00; /* block selector */
rsp = intf->sendrecv(intf, &req); rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode) { if (NULL != rsp) {
lprintf(LOG_ERR, "Error:%x Error requesting SOL parameter %d", switch (rsp->ccode) {
rsp ? rsp->ccode : 0, case 0x00:
data[1]); if (rsp->data_len == 2) {
return -1; 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));
} }
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->force_encryption = ((rsp->data[1] & 0x80)? 1 : 0);
params->force_authentication = ((rsp->data[1] & 0x40)? 1 : 0);
params->privilege_level = rsp->data[1] & 0x0F;
/* /*
* Character accumulate interval and character send interval * Character accumulate interval and character send interval
@ -185,23 +233,33 @@ ipmi_get_sol_info(
data[3] = 0x00; /* block selector */ data[3] = 0x00; /* block selector */
rsp = intf->sendrecv(intf, &req); rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode) { if (NULL != rsp) {
lprintf(LOG_ERR, "Error:%x Error requesting SOL parameter %d", switch (rsp->ccode) {
rsp ? rsp->ccode : 0, case 0x00:
data[1]); if (rsp->data_len == 3) {
return -1; 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));
} }
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;
}
params->character_accumulate_level = rsp->data[1];
params->character_send_threshold = rsp->data[2];
/* /*
* SOL retry * SOL retry
@ -213,23 +271,33 @@ ipmi_get_sol_info(
data[3] = 0x00; /* block selector */ data[3] = 0x00; /* block selector */
rsp = intf->sendrecv(intf, &req); rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode) { if (NULL != rsp) {
lprintf(LOG_ERR, "Error:%x Error requesting SOL parameter %d", switch (rsp->ccode) {
rsp ? rsp->ccode : 0, case 0x00:
data[1]); if (rsp->data_len == 3) {
return -1; 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));
} }
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;
}
params->retry_count = rsp->data[1];
params->retry_interval = rsp->data[2];
/* /*
* SOL non-volatile bit rate * SOL non-volatile bit rate
@ -241,22 +309,32 @@ ipmi_get_sol_info(
data[3] = 0x00; /* block selector */ data[3] = 0x00; /* block selector */
rsp = intf->sendrecv(intf, &req); rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode) { if (NULL != rsp) {
lprintf(LOG_ERR, "Error:%x Error requesting SOL parameter %d", switch (rsp->ccode) {
rsp ? rsp->ccode : 0, case 0x00:
data[1]); if (rsp->data_len == 2) {
return -1; 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));
} }
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->non_volatile_bit_rate = rsp->data[1] & 0x0F;
/* /*
* SOL volatile bit rate * SOL volatile bit rate
@ -268,22 +346,32 @@ ipmi_get_sol_info(
data[3] = 0x00; /* block selector */ data[3] = 0x00; /* block selector */
rsp = intf->sendrecv(intf, &req); rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode) { if (NULL != rsp) {
lprintf(LOG_ERR, "Error:%x Error requesting SOL parameter %d", switch (rsp->ccode) {
rsp ? rsp->ccode : 0, case 0x00:
data[1]); if (rsp->data_len == 2) {
return -1; 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));
} }
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->volatile_bit_rate = rsp->data[1] & 0x0F;
/* /*
* SOL payload channel * SOL payload channel
@ -295,22 +383,33 @@ ipmi_get_sol_info(
data[3] = 0x00; /* block selector */ data[3] = 0x00; /* block selector */
rsp = intf->sendrecv(intf, &req); rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode) { if (NULL != rsp) {
lprintf(LOG_ERR, "Error:%x Error requesting SOL parameter %d", switch (rsp->ccode) {
rsp ? rsp->ccode : 0, case 0x00:
data[1]); if (rsp->data_len == 2) {
return -1; 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));
} }
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->payload_channel = rsp->data[1];
/* /*
* SOL payload port * SOL payload port
@ -322,21 +421,33 @@ ipmi_get_sol_info(
data[3] = 0x00; /* block selector */ data[3] = 0x00; /* block selector */
rsp = intf->sendrecv(intf, &req); rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode) { if (NULL != rsp) {
lprintf(LOG_ERR, "Error:%x Error requesting SOL parameter %d", switch (rsp->ccode) {
rsp ? rsp->ccode : 0, case 0x00:
data[1]); if (rsp->data_len == 3) {
return -1; 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));
} }
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;
}
params->payload_port = (rsp->data[1]) | (rsp->data[2] << 8);
return 0; return 0;
} }
@ -349,7 +460,7 @@ ipmi_get_sol_info(
static int static int
ipmi_print_sol_info(struct ipmi_intf * intf, uint8_t channel) 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, &params)) if (ipmi_get_sol_info(intf, channel, &params))
return -1; return -1;
@ -405,8 +516,8 @@ ipmi_print_sol_info(struct ipmi_intf * intf, uint8_t channel)
printf("Non-Volatile Bit Rate (kbps) : %s\n", printf("Non-Volatile Bit Rate (kbps) : %s\n",
val2str(params.non_volatile_bit_rate, impi_bit_rate_vals)); val2str(params.non_volatile_bit_rate, impi_bit_rate_vals));
printf("Payload Channel : %d\n", printf("Payload Channel : %d (0x%02x)\n",
params.payload_channel); params.payload_channel, params.payload_channel);
printf("Payload Port : %d\n", printf("Payload Port : %d\n",
params.payload_port); params.payload_port);
} }
@ -804,11 +915,14 @@ ipmi_sol_set_param(struct ipmi_intf * intf,
/* The command proper */ /* The command proper */
rsp = intf->sendrecv(intf, &req); rsp = intf->sendrecv(intf, &req);
if (rsp == NULL) {
lprintf(LOG_ERR, "Error setting SOL parameter '%s'", param);
return -1;
}
if (!rsp || rsp->ccode) { if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Error:%x Error setting SOL parameter %s", lprintf(LOG_ERR, "Error setting SOL parameter '%s': %s",
rsp ? rsp->ccode : 0, param, val2str(rsp->ccode, completion_code_vals));
param);
if (bGuarded && if (bGuarded &&
(ipmi_sol_set_param(intf, (ipmi_sol_set_param(intf,
@ -1003,13 +1117,26 @@ ipmi_sol_deactivate(struct ipmi_intf * intf)
rsp = intf->sendrecv(intf, &req); rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode) { if (NULL != rsp) {
lprintf(LOG_ERR, "Error:%x Dectivating SOL payload", switch (rsp->ccode) {
rsp ? rsp->ccode : 0); case 0x00:
return -1; 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;
} }
@ -1303,19 +1430,44 @@ ipmi_sol_activate(struct ipmi_intf * intf)
rsp = intf->sendrecv(intf, &req); rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode) { if (NULL != rsp) {
lprintf(LOG_ERR, "Error:%x Activating SOL payload", switch (rsp->ccode) {
rsp ? rsp->ccode : 0); case 0x00:
return -1; if (rsp->data_len == 12) {
} break;
if (rsp->data_len != 12) } else {
{ lprintf(LOG_ERR, "Error: Unexpected data length (%d) received "
lprintf(LOG_ERR, "Error: Unexpected data length (%d) received " "in payload activation response",
"in payload activation response", rsp->data_len);
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; return -1;
} }
memcpy(&ap_rsp, rsp->data, sizeof(struct activate_payload_rsp)); memcpy(&ap_rsp, rsp->data, sizeof(struct activate_payload_rsp));
intf->session->sol_data.max_inbound_payload_size = intf->session->sol_data.max_inbound_payload_size =

View File

@ -254,3 +254,25 @@ const struct valstr completion_code_vals[] = {
{ 0x00, NULL } { 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 }
};

View File

@ -259,8 +259,8 @@ ipmi_print_user_list(
++current_user_id; ++current_user_id;
} while((current_user_id < user_access.maximum_ids) && } while((current_user_id <= user_access.maximum_ids) &&
(current_user_id < 63)); /* Absolute maximum allowed by spec */ (current_user_id <= 63)); /* Absolute maximum allowed by spec */
return 0; return 0;
@ -457,8 +457,8 @@ print_user_usage()
lprintf(LOG_NOTICE, " list [<channel number>]"); lprintf(LOG_NOTICE, " list [<channel number>]");
lprintf(LOG_NOTICE, " set name <user id> <username>"); lprintf(LOG_NOTICE, " set name <user id> <username>");
lprintf(LOG_NOTICE, " set password <user id> [<password>]"); lprintf(LOG_NOTICE, " set password <user id> [<password>]");
lprintf(LOG_NOTICE, " disable <user id> [<channel number>]"); lprintf(LOG_NOTICE, " disable <user id>");
lprintf(LOG_NOTICE, " enable <user id> [<channel number>]"); lprintf(LOG_NOTICE, " enable <user id>");
lprintf(LOG_NOTICE, " test <user id> <16|20> [<password]>\n"); lprintf(LOG_NOTICE, " test <user id> <16|20> [<password]>\n");
} }
@ -484,8 +484,6 @@ ipmi_user_main(struct ipmi_intf * intf, int argc, char ** argv)
{ {
int retval = 0; int retval = 0;
ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN);
/* /*
* Help * Help
*/ */

View File

@ -143,6 +143,7 @@ void log_halt(void)
closelog(); closelog();
free(logpriv); free(logpriv);
logpriv = NULL;
} }
int log_level_get(void) int log_level_get(void)

View File

@ -230,18 +230,26 @@ int ipmi_set_main(struct ipmi_intf * intf, int argc, char ** argv)
printf("Set session password\n"); printf("Set session password\n");
} }
else if (strncmp(argv[0], "authtype", 8) == 0) { else if (strncmp(argv[0], "authtype", 8) == 0) {
uint8_t authtype; int authtype;
authtype = (uint8_t)str2val(argv[1], ipmi_authtype_session_vals); authtype = str2val(argv[1], ipmi_authtype_session_vals);
ipmi_intf_session_set_authtype(intf, authtype); if (authtype < 0) {
printf("Set session authtype to %s\n", lprintf(LOG_ERR, "Invalid authtype: %s", argv[1]);
val2str(intf->session->authtype_set, ipmi_authtype_session_vals)); } 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) { else if (strncmp(argv[0], "privlvl", 7) == 0) {
uint8_t privlvl; int privlvl;
privlvl = (uint8_t)str2val(argv[1], ipmi_privlvl_vals); privlvl = str2val(argv[1], ipmi_privlvl_vals);
ipmi_intf_session_set_privlvl(intf, privlvl); if (privlvl < 0) {
printf("Set session privilege level to %s\n", lprintf(LOG_ERR, "Invalid privilege level: %s", argv[1]);
val2str(intf->session->privlvl, ipmi_privlvl_vals)); } 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) { else if (strncmp(argv[0], "port", 4) == 0) {
int port = atoi(argv[1]); int port = atoi(argv[1]);
@ -267,7 +275,7 @@ int ipmi_exec_main(struct ipmi_intf * intf, int argc, char ** argv)
{ {
FILE * fp; FILE * fp;
char buf[EXEC_BUF_SIZE]; char buf[EXEC_BUF_SIZE];
char * ptr, * tok, * ret; char * ptr, * tok, * ret, * tmp;
int __argc, i, r; int __argc, i, r;
char * __argv[EXEC_ARG_SIZE]; char * __argv[EXEC_ARG_SIZE];
int rc=0; int rc=0;
@ -293,6 +301,29 @@ int ipmi_exec_main(struct ipmi_intf * intf, int argc, char ** argv)
else else
ptr = buf + strlen(buf); ptr = buf + strlen(buf);
/* change "" and '' with spaces in the middle to ~
* this is really ugly but I'm in a hurry */
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 */ /* clip off trailing and leading whitespace */
ptr--; ptr--;
while (isspace(*ptr) && ptr >= buf) while (isspace(*ptr) && ptr >= buf)
@ -305,16 +336,33 @@ int ipmi_exec_main(struct ipmi_intf * intf, int argc, char ** argv)
/* parse it and make argument list */ /* parse it and make argument list */
__argc = 0; __argc = 0;
tok = strtok(ptr, " "); for (tok = strtok(ptr, " "); tok != NULL; tok = strtok(NULL, " ")) {
while (tok) {
if (__argc < EXEC_ARG_SIZE) { if (__argc < EXEC_ARG_SIZE) {
__argv[__argc++] = strdup(tok); __argv[__argc++] = strdup(tok);
if (__argv[__argc-1] == NULL) { if (__argv[__argc-1] == NULL) {
lprintf(LOG_ERR, "ipmitool: malloc failure"); lprintf(LOG_ERR, "ipmitool: malloc failure");
return -1; 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 */ /* now run the command, save the result if not successful */

View File

@ -53,6 +53,7 @@
#include <ipmitool/ipmi_sel.h> #include <ipmitool/ipmi_sel.h>
#include <ipmitool/ipmi_fru.h> #include <ipmitool/ipmi_fru.h>
#include <ipmitool/ipmi_sol.h> #include <ipmitool/ipmi_sol.h>
#include <ipmitool/ipmi_isol.h>
#include <ipmitool/ipmi_lanp.h> #include <ipmitool/ipmi_lanp.h>
#include <ipmitool/ipmi_chassis.h> #include <ipmitool/ipmi_chassis.h>
#include <ipmitool/ipmi_mc.h> #include <ipmitool/ipmi_mc.h>
@ -72,7 +73,7 @@
#ifdef __sun #ifdef __sun
# define OPTION_STRING "I:hVvcH:f:U:p:" # define OPTION_STRING "I:hVvcH:f:U:p:"
#else #else
# define OPTION_STRING "I:hVvcgsEao:H:P:f:U:p:L:A:t:m:" # define OPTION_STRING "I:hVvcgsEao:H:P:f:U:p:C:L:A:t:m:"
#endif #endif
int csv_output = 0; int csv_output = 0;
@ -98,12 +99,14 @@ struct ipmi_cmd {
{ ipmi_chassis_main, "chassis", "Get chassis status and set power state" }, { ipmi_chassis_main, "chassis", "Get chassis status and set power state" },
{ ipmi_event_main, "event", "Send pre-defined events to MC" }, { ipmi_event_main, "event", "Send pre-defined events to MC" },
{ ipmi_mc_main, "mc", "Management Controller status and global enables" }, { 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_sdr_main, "sdr", "Print Sensor Data Repository entries and readings" },
{ ipmi_sensor_main, "sensor", "Print detailed sensor information" }, { ipmi_sensor_main, "sensor", "Print detailed sensor information" },
{ ipmi_fru_main, "fru", "Print built-in FRU and scan SDR for FRU locators" }, { ipmi_fru_main, "fru", "Print built-in FRU and scan SDR for FRU locators" },
{ ipmi_sel_main, "sel", "Print System Event Log (SEL)" }, { ipmi_sel_main, "sel", "Print System Event Log (SEL)" },
{ ipmi_pef_main, "pef", "Configure Platform Event Filtering (PEF)" }, { ipmi_pef_main, "pef", "Configure Platform Event Filtering (PEF)" },
{ ipmi_sol_main, "sol", "Configure IPMIv2.0 Serial-over-LAN" }, { ipmi_sol_main, "sol", "Configure IPMIv2.0 Serial-over-LAN" },
{ ipmi_isol_main, "isol", "Configure IPMIv1.5 Serial-over-LAN" },
{ ipmi_user_main, "user", "Configure Management Controller users" }, { ipmi_user_main, "user", "Configure Management Controller users" },
{ ipmi_channel_main, "channel", "Configure Management Controller channels" }, { ipmi_channel_main, "channel", "Configure Management Controller channels" },
{ ipmi_session_main, "session", "Print session information" }, { ipmi_session_main, "session", "Print session information" },
@ -169,24 +172,25 @@ ipmitool_usage(void)
{ {
lprintf(LOG_NOTICE, "ipmitool version %s\n", VERSION); lprintf(LOG_NOTICE, "ipmitool version %s\n", VERSION);
lprintf(LOG_NOTICE, "usage: ipmitool [options...] <command>\n"); lprintf(LOG_NOTICE, "usage: ipmitool [options...] <command>\n");
lprintf(LOG_NOTICE, " -h This help"); lprintf(LOG_NOTICE, " -h This help");
lprintf(LOG_NOTICE, " -V Show version information"); lprintf(LOG_NOTICE, " -V Show version information");
lprintf(LOG_NOTICE, " -v Verbose (can use multiple times)"); lprintf(LOG_NOTICE, " -v Verbose (can use multiple times)");
lprintf(LOG_NOTICE, " -c Display output in comma separated format"); lprintf(LOG_NOTICE, " -c Display output in comma separated format");
lprintf(LOG_NOTICE, " -I intf Interface to use"); lprintf(LOG_NOTICE, " -I intf Interface to use");
lprintf(LOG_NOTICE, " -H hostname Remote host name for LAN interface"); lprintf(LOG_NOTICE, " -H hostname Remote host name for LAN interface");
lprintf(LOG_NOTICE, " -p port Remote RMCP port [default=623]"); lprintf(LOG_NOTICE, " -p port Remote RMCP port [default=623]");
lprintf(LOG_NOTICE, " -U username Remote session username"); lprintf(LOG_NOTICE, " -U username Remote session username");
lprintf(LOG_NOTICE, " -f file Read remote session password from file"); lprintf(LOG_NOTICE, " -f file Read remote session password from file");
lprintf(LOG_NOTICE, " -C ciphersuite Cipher suite to be used by lanplus interface");
#ifndef __sun #ifndef __sun
lprintf(LOG_NOTICE, " -L level Remote session privilege level [default=USER]"); 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, " -A authtype Force use of auth type NONE, PASSWORD, MD2, MD5 or OEM");
lprintf(LOG_NOTICE, " -P password Remote session password"); lprintf(LOG_NOTICE, " -P password Remote session password");
lprintf(LOG_NOTICE, " -a Prompt for remote password"); lprintf(LOG_NOTICE, " -a Prompt for remote password");
lprintf(LOG_NOTICE, " -E Read password from IPMI_PASSWORD environment variable"); lprintf(LOG_NOTICE, " -E Read password from IPMI_PASSWORD environment variable");
lprintf(LOG_NOTICE, " -m address Set local IPMB address"); lprintf(LOG_NOTICE, " -m address Set local IPMB address");
lprintf(LOG_NOTICE, " -t address Bridge request to remote target 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)"); lprintf(LOG_NOTICE, " -o oemtype Setup for OEM (use 'list' to see available OEM types)");
#endif #endif
lprintf(LOG_NOTICE, ""); lprintf(LOG_NOTICE, "");
ipmi_intf_print(); ipmi_intf_print();
@ -256,6 +260,7 @@ main(int argc, char ** argv)
char * progname = NULL; char * progname = NULL;
char * oemtype = NULL; char * oemtype = NULL;
int port = 0; int port = 0;
int cipher_suite_id = 3; /* See table 22-19 of the IPMIv2 spec */
int argflag, i; int argflag, i;
int rc = -1; int rc = -1;
@ -275,15 +280,20 @@ main(int argc, char ** argv)
break; break;
case 'h': case 'h':
ipmitool_usage(); ipmitool_usage();
rc = 0;
goto out_free; goto out_free;
break; break;
case 'V': case 'V':
printf("%s version %s\n", progname, VERSION); printf("%s version %s\n", progname, VERSION);
rc = 0;
goto out_free; goto out_free;
break; break;
case 'p': case 'p':
port = atoi(optarg); port = atoi(optarg);
break; break;
case 'C':
cipher_suite_id = atoi(optarg);
break;
case 'v': case 'v':
verbose++; verbose++;
break; break;
@ -415,9 +425,12 @@ main(int argc, char ** argv)
} }
if (strncmp(argv[optind], "help", 4) == 0) { if (strncmp(argv[optind], "help", 4) == 0) {
ipmi_cmd_print(); ipmi_cmd_print();
rc = 0;
goto out_free; goto out_free;
} }
/* /*
* If the user has specified a hostname (-H option) * If the user has specified a hostname (-H option)
* then this is a remote access session. * then this is a remote access session.
@ -489,6 +502,8 @@ main(int argc, char ** argv)
ipmi_intf_session_set_privlvl(intf, ipmi_intf_session_set_privlvl(intf,
IPMI_SESSION_PRIV_ADMIN); /* default */ IPMI_SESSION_PRIV_ADMIN); /* default */
ipmi_intf_session_set_cipher_suite_id(intf, cipher_suite_id);
/* setup IPMB local and target address if given */ /* setup IPMB local and target address if given */
intf->my_addr = my_addr ? : IPMI_BMC_SLAVE_ADDR; intf->my_addr = my_addr ? : IPMI_BMC_SLAVE_ADDR;
if (target_addr > 0) { if (target_addr > 0) {

View File

@ -48,6 +48,8 @@
#include <string.h> #include <string.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stropts.h> #include <sys/stropts.h>
#include <stddef.h>
#include <stropts.h>
#include <ipmitool/ipmi.h> #include <ipmitool/ipmi.h>
#include <ipmitool/ipmi_intf.h> #include <ipmitool/ipmi_intf.h>
@ -56,8 +58,19 @@
#include "bmc.h" #include "bmc.h"
static int curr_seq; 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; 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 = { struct ipmi_intf ipmi_bmc_intf = {
name: "bmc", name: "bmc",
desc: "IPMI v2.0 BMC interface", desc: "IPMI v2.0 BMC interface",
@ -78,6 +91,8 @@ ipmi_bmc_close(struct ipmi_intf *intf)
int int
ipmi_bmc_open(struct ipmi_intf *intf) ipmi_bmc_open(struct ipmi_intf *intf)
{ {
int method;
if (!intf) if (!intf)
return -1; return -1;
@ -91,20 +106,36 @@ ipmi_bmc_open(struct ipmi_intf *intf)
curr_seq = 0; curr_seq = 0;
intf->opened = 1; 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); return (intf->fd);
} }
struct ipmi_rs * struct ipmi_rs *
ipmi_bmc_send_cmd(struct ipmi_intf *intf, struct ipmi_rq *req) 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 not already opened open the device or network connection */
if (!intf->opened && intf->open && intf->open(intf) < 0) if (!intf->opened && intf->open && intf->open(intf) < 0)
return NULL; 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)); memset(&reqrsp, 0, sizeof (reqrsp));
reqrsp.req.fn = req->msg.netfn; reqrsp.req.fn = req->msg.netfn;
reqrsp.req.lun = 0; 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); istr.ic_len = sizeof (struct bmc_reqrsp);
if (verbose) { if (verbose) {
printf("BMC req.fn : %x\n", reqrsp.req.fn); printf("--\n");
printf("BMC req.lun : %x\n", reqrsp.req.lun); dump_request(&reqrsp.req);
printf("BMC req.cmd : %x\n", reqrsp.req.cmd); printf("--\n");
printf("BMC req.datalength : %d\n", reqrsp.req.datalength);
} }
if (ioctl(intf->fd, I_STR, &istr) < 0) { if (ioctl(intf->fd, I_STR, &istr) < 0) {
perror("BMC IOCTL: I_STR"); perror("BMC IOCTL: I_STR");
return (NULL); return (NULL);
} }
if (verbose > 2) {
dump_response(&reqrsp.rsp);
printf("--\n");
}
memset(&rsp, 0, sizeof (struct ipmi_rs)); memset(&rsp, 0, sizeof (struct ipmi_rs));
rsp.ccode = reqrsp.rsp.ccode; rsp.ccode = reqrsp.rsp.ccode;
rsp.data_len = reqrsp.rsp.datalength; 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); memcpy(rsp.data, reqrsp.rsp.data, rsp.data_len);
return (&rsp); 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");
}

View File

@ -34,10 +34,10 @@
* facility. * facility.
*/ */
#ifndef _BMC_INTF_H_ #ifndef _BMC_INTF_H
#define _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 #ifdef __cplusplus
extern "C" { extern "C" {
@ -46,13 +46,6 @@ extern "C" {
#define BMC_SUCCESS 0x0 #define BMC_SUCCESS 0x0
#define BMC_FAILURE 0x1 #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_CHASSIS 0x0
#define BMC_NETFN_BRIDGE 0x2 #define BMC_NETFN_BRIDGE 0x2
#define BMC_NETFN_SE 0x4 #define BMC_NETFN_SE 0x4
@ -95,27 +88,38 @@ extern "C" {
#define IOCTL_IPMI_KCS_ACTION 0x01 #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 * bmc_req_t is the data structure to send
* request packet from applications to the driver * request packet from applications to the driver
* module. * module.
*
* the request pkt is mainly for KCS-interface-BMC * the request pkt is mainly for KCS-interface-BMC
* messages. Since the system interface is session-less * messages. Since the system interface is session-less
* connections, the packet won't have any session * connections, the packet won't have any session
* information. * information.
*
* the data payload will be 2 bytes less than max * the data payload will be 2 bytes less than max
* BMC supported packet size. * BMC supported packet size.
* the address of the responder is always BMC and so * the address of the responder is always BMC and so
* rsSa field is not required. * rsSa field is not required.
*/ */
typedef struct bmc_req { typedef struct bmc_req {
unsigned char fn; /* netFn for command */ uint8_t fn; /* netFn for command */
unsigned char lun; /* logical unit on responder */ uint8_t lun; /* logical unit on responder */
unsigned char cmd; /* command */ uint8_t cmd; /* command */
unsigned char datalength; /* length of following data */ uint8_t datalength; /* length of following data */
unsigned char data[SEND_MAX_PAYLOAD_SIZE]; /* request data */ uint8_t data[SEND_MAX_PAYLOAD_SIZE]; /* request data */
} bmc_req_t; } bmc_req_t;
/* /*
@ -127,20 +131,21 @@ typedef struct bmc_req {
* messages. Since the system interface is session-less * messages. Since the system interface is session-less
* connections, the packet won't have any session * connections, the packet won't have any session
* information. * information.
*
* the data payload will be 2 bytes less than max * the data payload will be 2 bytes less than max
* BMC supported packet size. * BMC supported packet size.
*/ */
typedef struct bmc_rsp { typedef struct bmc_rsp {
unsigned char fn; /* netFn for command */ uint8_t fn; /* netFn for command */
unsigned char lun; /* logical unit on responder */ uint8_t lun; /* logical unit on responder */
unsigned char cmd; /* command */ uint8_t cmd; /* command */
unsigned char ccode; /* completion code */ uint8_t ccode; /* completion code */
unsigned char datalength; /* Length */ uint8_t datalength; /* Length */
unsigned char data[RECV_MAX_PAYLOAD_SIZE]; /* response */ uint8_t data[RECV_MAX_PAYLOAD_SIZE]; /* response */
} bmc_rsp_t; } bmc_rsp_t;
/* /*
* the data structure for synchronous operation. * the data structure for synchronous operation via ioctl (DEPRECATED)
*/ */
typedef struct bmc_reqrsp { typedef struct bmc_reqrsp {
bmc_req_t req; /* request half */ bmc_req_t req; /* request half */
@ -148,38 +153,59 @@ typedef struct bmc_reqrsp {
} bmc_reqrsp_t; } 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. * An error response passed back from the bmc driver will have its m_id
* Ref. IPMI Spec 9.2 * 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 { #define BMC_UNKNOWN_MSG_ID ~((uint32_t)0)
unsigned char fnlun; /* Network Function and LUN */
unsigned char cmd; /* command */
unsigned char data[SEND_MAX_PAYLOAD_SIZE];
} bmc_send_t;
/* /*
* data structure to receive a message from BMC. * Possible values for the m_type field in bmc_msg_t:
* Ref. IPMI Spec 9.3
*/ */
typedef struct bmc_recv { #define BMC_MSG_REQUEST 1 /* BMC request (as above, sent to the */
unsigned char fnlun; /* Network Function and LUN */ /* driver by the user), bmc_msg.msg */
unsigned char cmd; /* command */ /* begins with the bmc_req_t */
unsigned char ccode; /* completion code */ /* structure. */
unsigned char data[RECV_MAX_PAYLOAD_SIZE]; #define BMC_MSG_RESPONSE 2 /* BMC response (sent by the driver) */
} bmc_recv_t; /* bmc_msg.msg begins with the */
/* bmc_rsp_t structure. */
#define BMC_MSG_ERROR 3 /* Error while processing a user msg */
#endif /* _KERNEL */ /* msg[0] is the error code */
/* (interpret as an errno value) */
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#ifdef __cplusplus #endif /* _BMC_INTF_H */
}
#endif
#endif /* _BMC_INTF_H_ */

View File

@ -200,6 +200,15 @@ ipmi_intf_session_set_privlvl(struct ipmi_intf * intf, uint8_t level)
intf->session->privlvl = 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 void
ipmi_intf_session_set_port(struct ipmi_intf * intf, int port) ipmi_intf_session_set_port(struct ipmi_intf * intf, int port)
{ {

View File

@ -101,40 +101,6 @@ query_alarm(int signo)
siglongjmp(jmpbuf, 1); 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 * static struct ipmi_rq_entry *
ipmi_req_add_entry(struct ipmi_intf * intf, struct ipmi_rq * req) ipmi_req_add_entry(struct ipmi_intf * intf, struct ipmi_rq * req)
@ -329,7 +295,7 @@ ipmi_handle_pong(struct ipmi_intf * intf, struct ipmi_rs * rsp)
" ASF Version %s\n" " ASF Version %s\n"
" RMCP Version %s\n" " RMCP Version %s\n"
" RMCP Sequence %d\n" " RMCP Sequence %d\n"
" IANA Enterprise %d\n", " IANA Enterprise %ld\n",
(pong->sup_entities & 0x80) ? "" : " NOT", (pong->sup_entities & 0x80) ? "" : " NOT",
(pong->sup_entities & 0x01) ? "1.0" : "unknown", (pong->sup_entities & 0x01) ? "1.0" : "unknown",
(pong->rmcp.ver == 6) ? "1.0" : "unknown", (pong->rmcp.ver == 6) ? "1.0" : "unknown",
@ -362,7 +328,7 @@ int
ipmi_lan_ping(struct ipmi_intf * intf) ipmi_lan_ping(struct ipmi_intf * intf)
{ {
struct asf_hdr asf_ping = { struct asf_hdr asf_ping = {
.iana = ASF_RMCP_IANA, .iana = htonl(ASF_RMCP_IANA),
.type = ASF_TYPE_PING, .type = ASF_TYPE_PING,
}; };
struct rmcp_hdr rmcp_ping = { struct rmcp_hdr rmcp_ping = {
@ -1127,7 +1093,7 @@ ipmi_activate_session_cmd(struct ipmi_intf * intf)
printbuf(rsp->data, rsp->data_len, "activate_session"); printbuf(rsp->data, rsp->data_len, "activate_session");
if (rsp->ccode) { if (rsp->ccode) {
lprintf(LOG_ERR, "Activate Session error:"); fprintf(stderr, "Activate Session error:");
switch (rsp->ccode) { switch (rsp->ccode) {
case 0x81: case 0x81:
lprintf(LOG_ERR, "\tNo session slot available"); lprintf(LOG_ERR, "\tNo session slot available");
@ -1295,7 +1261,7 @@ ipmi_lan_activate_session(struct ipmi_intf * intf)
/* don't fail on ping because its not always supported. /* don't fail on ping because its not always supported.
* Supermicro's IPMI LAN 1.5 cards don't tolerate pings. * 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); ipmi_lan_ping(intf);
/* Some particular Intel boards need special help /* Some particular Intel boards need special help
@ -1378,7 +1344,11 @@ int ipmi_lan_open(struct ipmi_intf * intf)
s->addr.sin_family = AF_INET; s->addr.sin_family = AF_INET;
s->addr.sin_port = htons(s->port); 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); rc = inet_pton(AF_INET, s->hostname, &s->addr.sin_addr);
#endif
if (rc <= 0) { if (rc <= 0) {
struct hostent *host = gethostbyname(s->hostname); struct hostent *host = gethostbyname(s->hostname);
if (host == NULL) { if (host == NULL) {

View File

@ -50,13 +50,16 @@
#include <fcntl.h> #include <fcntl.h>
#include <assert.h> #include <assert.h>
#include <config.h> #ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <ipmitool/helper.h> #include <ipmitool/helper.h>
#include <ipmitool/log.h> #include <ipmitool/log.h>
#include <ipmitool/ipmi.h> #include <ipmitool/ipmi.h>
#include <ipmitool/ipmi_lanp.h> #include <ipmitool/ipmi_lanp.h>
#include <ipmitool/ipmi_channel.h> #include <ipmitool/ipmi_channel.h>
#include <ipmitool/ipmi_intf.h> #include <ipmitool/ipmi_intf.h>
#include <ipmitool/ipmi_strings.h>
#include <ipmitool/bswap.h> #include <ipmitool/bswap.h>
#include <openssl/rand.h> #include <openssl/rand.h>
@ -132,6 +135,115 @@ struct ipmi_intf ipmi_lanplus_intf = {
extern int verbose; extern int verbose;
/*
* lanplus_get_requested_ciphers
*
* Set the authentication, integrity and encryption algorithms based
* on the cipher suite ID. See table 22-19 in the IPMIv2 spec for the
* source of this information.
*
* param cipher_suite_id [in]
* param auth_alg [out]
* param integrity_alg [out]
* param crypt_alg [out]
*
* returns 0 on success
* 1 on failure
*/
int lanplus_get_requested_ciphers(int cipher_suite_id,
uint8_t * auth_alg,
uint8_t * integrity_alg,
uint8_t * crypt_alg)
{
if ((cipher_suite_id < 0) || (cipher_suite_id > 14))
return 1;
/* See table 22-19 for the source of the statement */
switch (cipher_suite_id)
{
case 0:
*auth_alg = IPMI_AUTH_RAKP_NONE;
*integrity_alg = IPMI_INTEGRITY_NONE;
*crypt_alg = IPMI_CRYPT_NONE;
break;
case 1:
*auth_alg = IPMI_AUTH_RAKP_HMAC_SHA1;
*integrity_alg = IPMI_INTEGRITY_NONE;
*crypt_alg = IPMI_CRYPT_NONE;
break;
case 2:
*auth_alg = IPMI_AUTH_RAKP_HMAC_SHA1;
*integrity_alg = IPMI_INTEGRITY_HMAC_SHA1_96;
*crypt_alg = IPMI_CRYPT_NONE;
break;
case 3:
*auth_alg = IPMI_AUTH_RAKP_HMAC_SHA1;
*integrity_alg = IPMI_INTEGRITY_HMAC_SHA1_96;
*crypt_alg = IPMI_CRYPT_AES_CBC_128;
break;
case 4:
*auth_alg = IPMI_AUTH_RAKP_HMAC_SHA1;
*integrity_alg = IPMI_INTEGRITY_HMAC_SHA1_96;
*crypt_alg = IPMI_CRYPT_XRC4_128;
break;
case 5:
*auth_alg = IPMI_AUTH_RAKP_HMAC_SHA1;
*integrity_alg = IPMI_INTEGRITY_HMAC_SHA1_96;
*crypt_alg = IPMI_CRYPT_XRC4_40;
break;
case 6:
*auth_alg = IPMI_AUTH_RAKP_HMAC_MD5;
*integrity_alg = IPMI_INTEGRITY_NONE;
*crypt_alg = IPMI_CRYPT_NONE;
break;
case 7:
*auth_alg = IPMI_AUTH_RAKP_HMAC_MD5;
*integrity_alg = IPMI_INTEGRITY_HMAC_MD5_128;
*crypt_alg = IPMI_CRYPT_NONE;
break;
case 8:
*auth_alg = IPMI_AUTH_RAKP_HMAC_MD5;
*integrity_alg = IPMI_INTEGRITY_HMAC_MD5_128;
*crypt_alg = IPMI_CRYPT_AES_CBC_128;
break;
case 9:
*auth_alg = IPMI_AUTH_RAKP_HMAC_MD5;
*integrity_alg = IPMI_INTEGRITY_HMAC_MD5_128;
*crypt_alg = IPMI_CRYPT_XRC4_128;
break;
case 10:
*auth_alg = IPMI_AUTH_RAKP_HMAC_MD5;
*integrity_alg = IPMI_INTEGRITY_HMAC_MD5_128;
*crypt_alg = IPMI_CRYPT_XRC4_40;
break;
case 11:
*auth_alg = IPMI_AUTH_RAKP_HMAC_MD5;
*integrity_alg = IPMI_INTEGRITY_MD5_128;
*crypt_alg = IPMI_CRYPT_NONE;
break;
case 12:
*auth_alg = IPMI_AUTH_RAKP_HMAC_MD5;
*integrity_alg = IPMI_INTEGRITY_MD5_128;
*crypt_alg = IPMI_CRYPT_AES_CBC_128;
break;
case 13:
*auth_alg = IPMI_AUTH_RAKP_HMAC_MD5;
*integrity_alg = IPMI_INTEGRITY_MD5_128;
*crypt_alg = IPMI_CRYPT_XRC4_128;
break;
case 14:
*auth_alg = IPMI_AUTH_RAKP_HMAC_MD5;
*integrity_alg = IPMI_INTEGRITY_MD5_128;
*crypt_alg = IPMI_CRYPT_XRC4_40;
break;
}
return 0;
}
/* /*
* Reverse the order of arbitrarily long strings of bytes * Reverse the order of arbitrarily long strings of bytes
*/ */
@ -159,38 +271,17 @@ query_alarm(int signo)
} }
static const struct valstr ipmi_channel_protocol_vals[] = { static const struct valstr plus_payload_types_vals[] = {
{ 0x00, "reserved" }, { IPMI_PAYLOAD_TYPE_IPMI, "IPMI (0)" }, // IPMI Message
{ 0x01, "IPMB-1.0" }, { IPMI_PAYLOAD_TYPE_SOL, "SOL (1)" }, // SOL (Serial over LAN)
{ 0x02, "ICMB-1.0" }, { IPMI_PAYLOAD_TYPE_OEM, "OEM (2)" }, // OEM Explicid
{ 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[] = { { IPMI_PAYLOAD_TYPE_RMCP_OPEN_REQUEST, "OpenSession Req (0x10)" },
{ 0x00, "reserved" }, { IPMI_PAYLOAD_TYPE_RMCP_OPEN_RESPONSE,"OpenSession Resp (0x11)" },
{ 0x01, "IPMB (I2C)" }, { IPMI_PAYLOAD_TYPE_RAKP_1, "RAKP1 (0x12)" },
{ 0x02, "ICMB v1.0" }, { IPMI_PAYLOAD_TYPE_RAKP_2, "RAKP2 (0x13)" },
{ 0x03, "ICMB v0.9" }, { IPMI_PAYLOAD_TYPE_RAKP_3, "RAKP3 (0x14)" },
{ 0x04, "802.3 LAN" }, { IPMI_PAYLOAD_TYPE_RAKP_4, "RAKP4 (0x15)" },
{ 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 }, { 0x00, NULL },
}; };
@ -372,11 +463,11 @@ ipmi_handle_pong(struct ipmi_intf * intf, struct ipmi_rs * rsp)
printf(" ASF Version %s\n" printf(" ASF Version %s\n"
" RMCP Version %s\n" " RMCP Version %s\n"
" RMCP Sequence %d\n" " RMCP Sequence %d\n"
" IANA Enterprise %d\n\n", " IANA Enterprise %lu\n\n",
(pong->sup_entities & 0x01) ? "1.0" : "unknown", (pong->sup_entities & 0x01) ? "1.0" : "unknown",
(pong->rmcp.ver == 6) ? "1.0" : "unknown", (pong->rmcp.ver == 6) ? "1.0" : "unknown",
pong->rmcp.seq, pong->rmcp.seq,
ntohl(pong->iana)); (unsigned long)ntohl(pong->iana));
return (pong->sup_entities & 0x80) ? 1 : 0; return (pong->sup_entities & 0x80) ? 1 : 0;
} }
@ -405,7 +496,7 @@ int
ipmiv2_lan_ping(struct ipmi_intf * intf) ipmiv2_lan_ping(struct ipmi_intf * intf)
{ {
struct asf_hdr asf_ping = { struct asf_hdr asf_ping = {
.iana = ASF_RMCP_IANA, .iana = htonl(ASF_RMCP_IANA),
.type = ASF_TYPE_PING, .type = ASF_TYPE_PING,
}; };
struct rmcp_hdr rmcp_ping = { struct rmcp_hdr rmcp_ping = {
@ -548,9 +639,9 @@ ipmi_lan_poll_recv(struct ipmi_intf * intf)
lprintf(LOG_DEBUG+1, "<< IPMI Response Session Header"); lprintf(LOG_DEBUG+1, "<< IPMI Response Session Header");
lprintf(LOG_DEBUG+1, "<< Authtype : %s", lprintf(LOG_DEBUG+1, "<< Authtype : %s",
val2str(rsp->session.authtype, ipmi_authtype_vals)); val2str(rsp->session.authtype, ipmi_authtype_session_vals));
lprintf(LOG_DEBUG+1, "<< Payload type : 0x%x", lprintf(LOG_DEBUG+1, "<< Payload type : %s",
rsp->session.payloadtype); val2str(rsp->session.payloadtype, plus_payload_types_vals));
lprintf(LOG_DEBUG+1, "<< Session ID : 0x%08lx", lprintf(LOG_DEBUG+1, "<< Session ID : 0x%08lx",
(long)rsp->session.id); (long)rsp->session.id);
lprintf(LOG_DEBUG+1, "<< Sequence : 0x%08lx", lprintf(LOG_DEBUG+1, "<< Sequence : 0x%08lx",
@ -601,6 +692,8 @@ ipmi_lan_poll_recv(struct ipmi_intf * intf)
rsp->data_len = extra_data_length; rsp->data_len = extra_data_length;
memmove(rsp->data, rsp->data + offset, extra_data_length); memmove(rsp->data, rsp->data + offset, extra_data_length);
} }
else
rsp->data_len = 0;
break; break;
} }
@ -655,7 +748,7 @@ ipmi_lan_poll_recv(struct ipmi_intf * intf)
continue; continue;
} }
read_rakp4_message(rsp, offset, session->v2_data.integrity_alg); read_rakp4_message(rsp, offset, session->v2_data.auth_alg);
break; break;
} }
@ -718,6 +811,9 @@ ipmi_lan_poll_recv(struct ipmi_intf * intf)
void void
read_open_session_response(struct ipmi_rs * rsp, int offset) read_open_session_response(struct ipmi_rs * rsp, int offset)
{ {
memset(&rsp->payload.open_session_response, 0,
sizeof(rsp->payload.open_session_response));
/* Message tag */ /* Message tag */
rsp->payload.open_session_response.message_tag = rsp->data[offset]; rsp->payload.open_session_response.message_tag = rsp->data[offset];
@ -727,6 +823,8 @@ read_open_session_response(struct ipmi_rs * rsp, int offset)
/* Maximum privilege level */ /* Maximum privilege level */
rsp->payload.open_session_response.max_priv_level = rsp->data[offset + 2]; rsp->payload.open_session_response.max_priv_level = rsp->data[offset + 2];
/*** offset + 3 is reserved ***/
/* Remote console session ID */ /* Remote console session ID */
memcpy(&(rsp->payload.open_session_response.console_id), memcpy(&(rsp->payload.open_session_response.console_id),
rsp->data + offset + 4, rsp->data + offset + 4,
@ -736,6 +834,11 @@ read_open_session_response(struct ipmi_rs * rsp, int offset)
BSWAP_32(rsp->payload.open_session_response.console_id); BSWAP_32(rsp->payload.open_session_response.console_id);
#endif #endif
/* 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;
/* BMC session ID */ /* BMC session ID */
memcpy(&(rsp->payload.open_session_response.bmc_id), memcpy(&(rsp->payload.open_session_response.bmc_id),
rsp->data + offset + 8, rsp->data + offset + 8,
@ -855,7 +958,7 @@ void
read_rakp4_message( read_rakp4_message(
struct ipmi_rs * rsp, struct ipmi_rs * rsp,
int offset, int offset,
uint8_t integrity_alg) uint8_t auth_alg)
{ {
int i; int i;
@ -876,23 +979,22 @@ read_rakp4_message(
/* Integrity check value */ /* Integrity check value */
switch (integrity_alg) switch (auth_alg)
{ {
case IPMI_INTEGRITY_NONE: case IPMI_AUTH_RAKP_NONE:
/* Nothing to do here */ /* Nothing to do here */
break; break;
case IPMI_INTEGRITY_HMAC_SHA1_96: case IPMI_AUTH_RAKP_HMAC_SHA1:
/* We need to copy 12 bytes */ /* We need to copy 12 bytes */
for (i = 0; i < 12; ++i) for (i = 0; i < 12; ++i)
rsp->payload.rakp4_message.integrity_check_value[i] = rsp->payload.rakp4_message.integrity_check_value[i] =
rsp->data[offset + 8 + i]; rsp->data[offset + 8 + i];
break; break;
case IPMI_INTEGRITY_HMAC_MD5_128: case IPMI_AUTH_RAKP_HMAC_MD5:
case IPMI_INTEGRITY_MD5_128:
lprintf(LOG_ERR, "read_rakp4_message: no support " lprintf(LOG_ERR, "read_rakp4_message: no support "
"for integrity algorithm 0x%x", integrity_alg); "for authentication algorithm 0x%x", auth_alg);
assert(0); assert(0);
break; break;
} }
@ -1337,22 +1439,23 @@ ipmi_lanplus_build_v2x_msg(
msg[IMPI_LANPLUS_OFFSET_PAYLOAD_TYPE] |= msg[IMPI_LANPLUS_OFFSET_PAYLOAD_TYPE] |=
((session->v2_data.crypt_alg != IPMI_CRYPT_NONE )? 0x80 : 0x00); ((session->v2_data.crypt_alg != IPMI_CRYPT_NONE )? 0x80 : 0x00);
msg[IMPI_LANPLUS_OFFSET_PAYLOAD_TYPE] |= msg[IMPI_LANPLUS_OFFSET_PAYLOAD_TYPE] |=
((session->v2_data.auth_alg != IPMI_AUTH_RAKP_NONE)? 0x40 : 0x00); ((session->v2_data.integrity_alg != IPMI_INTEGRITY_NONE)? 0x40 : 0x00);
} }
/* Session ID -- making it LSB */ if (session->v2_data.session_state == LANPLUS_STATE_ACTIVE)
msg[IMPI_LANPLUS_OFFSET_SESSION_ID ] = session->v2_data.bmc_id & 0xff; {
msg[IMPI_LANPLUS_OFFSET_SESSION_ID + 1] = (session->v2_data.bmc_id >> 8) & 0xff; /* Session ID -- making it LSB */
msg[IMPI_LANPLUS_OFFSET_SESSION_ID + 2] = (session->v2_data.bmc_id >> 16) & 0xff; msg[IMPI_LANPLUS_OFFSET_SESSION_ID ] = session->v2_data.bmc_id & 0xff;
msg[IMPI_LANPLUS_OFFSET_SESSION_ID + 3] = (session->v2_data.bmc_id >> 24) & 0xff; msg[IMPI_LANPLUS_OFFSET_SESSION_ID + 1] = (session->v2_data.bmc_id >> 8) & 0xff;
msg[IMPI_LANPLUS_OFFSET_SESSION_ID + 2] = (session->v2_data.bmc_id >> 16) & 0xff;
msg[IMPI_LANPLUS_OFFSET_SESSION_ID + 3] = (session->v2_data.bmc_id >> 24) & 0xff;
/* Sequence Number -- making it LSB */
msg[IMPI_LANPLUS_OFFSET_SEQUENCE_NUM ] = session->out_seq & 0xff;
msg[IMPI_LANPLUS_OFFSET_SEQUENCE_NUM + 1] = (session->out_seq >> 8) & 0xff;
msg[IMPI_LANPLUS_OFFSET_SEQUENCE_NUM + 2] = (session->out_seq >> 16) & 0xff;
msg[IMPI_LANPLUS_OFFSET_SEQUENCE_NUM + 3] = (session->out_seq >> 24) & 0xff;
/* Sequence Number -- making it LSB */
msg[IMPI_LANPLUS_OFFSET_SEQUENCE_NUM ] = session->out_seq & 0xff;
msg[IMPI_LANPLUS_OFFSET_SEQUENCE_NUM + 1] = (session->out_seq >> 8) & 0xff;
msg[IMPI_LANPLUS_OFFSET_SEQUENCE_NUM + 2] = (session->out_seq >> 16) & 0xff;
msg[IMPI_LANPLUS_OFFSET_SEQUENCE_NUM + 3] = (session->out_seq >> 24) & 0xff;
}
/* /*
* Payload Length is set below (we don't know how big the payload is until after * Payload Length is set below (we don't know how big the payload is until after
@ -1449,7 +1552,7 @@ ipmi_lanplus_build_v2x_msg(
*------------------------------------------ *------------------------------------------
*/ */
if ((session->v2_data.session_state == LANPLUS_STATE_ACTIVE) && if ((session->v2_data.session_state == LANPLUS_STATE_ACTIVE) &&
(session->v2_data.auth_alg != IPMI_AUTH_RAKP_NONE)) (session->v2_data.integrity_alg != IPMI_INTEGRITY_NONE))
{ {
uint32_t i, hmac_length, integrity_pad_size = 0, hmac_input_size; uint32_t i, hmac_length, integrity_pad_size = 0, hmac_input_size;
uint8_t * hmac_output; uint8_t * hmac_output;
@ -1502,7 +1605,7 @@ ipmi_lanplus_build_v2x_msg(
/* Auth Code */ /* Auth Code */
lanplus_HMAC(session->v2_data.auth_alg, lanplus_HMAC(session->v2_data.integrity_alg,
session->v2_data.k1, /* key */ session->v2_data.k1, /* key */
20, /* key length */ 20, /* key length */
msg + IMPI_LANPLUS_OFFSET_AUTHTYPE, /* hmac input */ msg + IMPI_LANPLUS_OFFSET_AUTHTYPE, /* hmac input */
@ -1718,7 +1821,7 @@ ipmi_lanplus_build_v15_ipmi_cmd(
lprintf(LOG_DEBUG+1, ">> IPMI Request Session Header"); lprintf(LOG_DEBUG+1, ">> IPMI Request Session Header");
lprintf(LOG_DEBUG+1, ">> Authtype : %s", lprintf(LOG_DEBUG+1, ">> Authtype : %s",
val2str(IPMI_SESSION_AUTHTYPE_NONE, ipmi_authtype_vals)); val2str(IPMI_SESSION_AUTHTYPE_NONE, ipmi_authtype_session_vals));
lprintf(LOG_DEBUG+1, ">> Sequence : 0x%08lx", lprintf(LOG_DEBUG+1, ">> Sequence : 0x%08lx",
(long)session->out_seq); (long)session->out_seq);
lprintf(LOG_DEBUG+1, ">> Session ID : 0x%08lx", lprintf(LOG_DEBUG+1, ">> Session ID : 0x%08lx",
@ -2273,7 +2376,6 @@ ipmi_lanplus_send_ipmi_cmd(
} }
/* /*
* ipmi_get_auth_capabilities_cmd * ipmi_get_auth_capabilities_cmd
* *
@ -2437,6 +2539,18 @@ ipmi_lanplus_open_session(struct ipmi_intf * intf)
msg[6] = (session->v2_data.console_id >> 16) & 0xff; msg[6] = (session->v2_data.console_id >> 16) & 0xff;
msg[7] = (session->v2_data.console_id >> 24) & 0xff; msg[7] = (session->v2_data.console_id >> 24) & 0xff;
if (lanplus_get_requested_ciphers(session->cipher_suite_id,
&(session->v2_data.requested_auth_alg),
&(session->v2_data.requested_integrity_alg),
&(session->v2_data.requested_crypt_alg)))
{
lprintf(LOG_WARNING, "Unsupported cipher suite ID : %d\n",
session->cipher_suite_id);
return -1;
}
/* /*
* Authentication payload * Authentication payload
*/ */
@ -2444,7 +2558,7 @@ ipmi_lanplus_open_session(struct ipmi_intf * intf)
msg[9] = 0; /* reserved */ msg[9] = 0; /* reserved */
msg[10] = 0; /* reserved */ msg[10] = 0; /* reserved */
msg[11] = 8; /* payload length */ msg[11] = 8; /* payload length */
msg[12] = IPMI_AUTH_RAKP_HMAC_SHA1; msg[12] = session->v2_data.requested_auth_alg;
msg[13] = 0; /* reserved */ msg[13] = 0; /* reserved */
msg[14] = 0; /* reserved */ msg[14] = 0; /* reserved */
msg[15] = 0; /* reserved */ msg[15] = 0; /* reserved */
@ -2456,7 +2570,7 @@ ipmi_lanplus_open_session(struct ipmi_intf * intf)
msg[17] = 0; /* reserved */ msg[17] = 0; /* reserved */
msg[18] = 0; /* reserved */ msg[18] = 0; /* reserved */
msg[19] = 8; /* payload length */ msg[19] = 8; /* payload length */
msg[20] = IPMI_INTEGRITY_HMAC_SHA1_96; msg[20] = session->v2_data.requested_integrity_alg;
msg[21] = 0; /* reserved */ msg[21] = 0; /* reserved */
msg[22] = 0; /* reserved */ msg[22] = 0; /* reserved */
msg[23] = 0; /* reserved */ msg[23] = 0; /* reserved */
@ -2468,7 +2582,7 @@ ipmi_lanplus_open_session(struct ipmi_intf * intf)
msg[25] = 0; /* reserved */ msg[25] = 0; /* reserved */
msg[26] = 0; /* reserved */ msg[26] = 0; /* reserved */
msg[27] = 8; /* payload length */ msg[27] = 8; /* payload length */
msg[28] = IPMI_CRYPT_AES_CBC_128; msg[28] = session->v2_data.requested_crypt_alg;
msg[29] = 0; /* reserved */ msg[29] = 0; /* reserved */
msg[30] = 0; /* reserved */ msg[30] = 0; /* reserved */
msg[31] = 0; /* reserved */ msg[31] = 0; /* reserved */
@ -2513,6 +2627,39 @@ ipmi_lanplus_open_session(struct ipmi_intf * intf)
rsp->payload.open_session_response.crypt_alg; rsp->payload.open_session_response.crypt_alg;
session->v2_data.session_state = session->v2_data.session_state =
LANPLUS_STATE_OPEN_SESSION_RECEIEVED; LANPLUS_STATE_OPEN_SESSION_RECEIEVED;
/*
* Verify that we have agreed on a cipher suite
*/
if (rsp->payload.open_session_response.auth_alg !=
session->v2_data.requested_auth_alg)
{
lprintf(LOG_WARNING, "Authentication algorithm 0x%02x is "
"not what we requested 0x%02x\n",
rsp->payload.open_session_response.auth_alg,
session->v2_data.requested_auth_alg);
rc = -1;
}
else if (rsp->payload.open_session_response.integrity_alg !=
session->v2_data.requested_integrity_alg)
{
lprintf(LOG_WARNING, "Integrity algorithm 0x%02x is "
"not what we requested 0x%02x\n",
rsp->payload.open_session_response.integrity_alg,
session->v2_data.requested_integrity_alg);
rc = -1;
}
else if (rsp->payload.open_session_response.crypt_alg !=
session->v2_data.requested_crypt_alg)
{
lprintf(LOG_WARNING, "Encryption algorithm 0x%02x is "
"not what we requested 0x%02x\n",
rsp->payload.open_session_response.crypt_alg,
session->v2_data.requested_crypt_alg);
rc = -1;
}
} }
return rc; return rc;
@ -2610,9 +2757,9 @@ ipmi_lanplus_rakp1(struct ipmi_intf * intf)
} }
memcpy(msg + 28, session->username, msg[27]); memcpy(msg + 28, session->username, msg[27]);
v2_payload.payload_type = IPMI_PAYLOAD_TYPE_RAKP_1; v2_payload.payload_type = IPMI_PAYLOAD_TYPE_RAKP_1;
v2_payload.payload_length = IPMI_RAKP1_MESSAGE_SIZE; v2_payload.payload_length =
IPMI_RAKP1_MESSAGE_SIZE - (16 - msg[27]);
v2_payload.payload.rakp_1_message.message = msg; v2_payload.payload.rakp_1_message.message = msg;
rsp = ipmi_lanplus_send_payload(intf, &v2_payload); rsp = ipmi_lanplus_send_payload(intf, &v2_payload);
@ -2643,12 +2790,15 @@ ipmi_lanplus_rakp1(struct ipmi_intf * intf)
memcpy(session->v2_data.bmc_rand, rsp->payload.rakp2_message.bmc_rand, 16); memcpy(session->v2_data.bmc_rand, rsp->payload.rakp2_message.bmc_rand, 16);
memcpy(session->v2_data.bmc_guid, rsp->payload.rakp2_message.bmc_guid, 16); memcpy(session->v2_data.bmc_guid, rsp->payload.rakp2_message.bmc_guid, 16);
printbuf(session->v2_data.bmc_rand, 16, "bmc_rand");
/* /*
* It is at this point that we have to decode the random number and determine * It is at this point that we have to decode the random number and determine
* whether the BMC has authenticated. * whether the BMC has authenticated.
*/ */
if (! lanplus_rakp2_hmac_matches(session, if (! lanplus_rakp2_hmac_matches(session,
rsp->payload.rakp2_message.key_exchange_auth_code)) rsp->payload.rakp2_message.key_exchange_auth_code,
intf))
{ {
/* Error */ /* Error */
lprintf(LOG_INFO, "> RAKP 2 HMAC is invalid"); lprintf(LOG_INFO, "> RAKP 2 HMAC is invalid");
@ -2717,7 +2867,7 @@ ipmi_lanplus_rakp3(struct ipmi_intf * intf)
v2_payload.payload_type = IPMI_PAYLOAD_TYPE_RAKP_3; v2_payload.payload_type = IPMI_PAYLOAD_TYPE_RAKP_3;
v2_payload.payload_length = 8; v2_payload.payload_length = 8;
v2_payload.payload.rakp_1_message.message = msg; v2_payload.payload.rakp_3_message.message = msg;
/* /*
* If the rakp2 return code indicates and error, we don't have to * If the rakp2 return code indicates and error, we don't have to
@ -2727,9 +2877,9 @@ ipmi_lanplus_rakp3(struct ipmi_intf * intf)
*/ */
if (session->v2_data.rakp2_return_code == IPMI_RAKP_STATUS_NO_ERRORS) if (session->v2_data.rakp2_return_code == IPMI_RAKP_STATUS_NO_ERRORS)
{ {
int auth_length; uint32_t auth_length;
if (lanplus_generate_rakp3_authcode(msg + 8, session, &auth_length)) if (lanplus_generate_rakp3_authcode(msg + 8, session, &auth_length, intf))
{ {
/* Error */ /* Error */
lprintf(LOG_INFO, "> Error generating RAKP 3 authcode"); lprintf(LOG_INFO, "> Error generating RAKP 3 authcode");
@ -2800,7 +2950,8 @@ ipmi_lanplus_rakp3(struct ipmi_intf * intf)
{ {
/* Validate the authcode */ /* Validate the authcode */
if (lanplus_rakp4_hmac_matches(session, if (lanplus_rakp4_hmac_matches(session,
rsp->payload.rakp4_message.integrity_check_value)) rsp->payload.rakp4_message.integrity_check_value,
intf))
{ {
/* Success */ /* Success */
session->v2_data.session_state = LANPLUS_STATE_ACTIVE; session->v2_data.session_state = LANPLUS_STATE_ACTIVE;
@ -2892,7 +3043,11 @@ ipmi_lanplus_open(struct ipmi_intf * intf)
addr.sin_family = AF_INET; addr.sin_family = AF_INET;
addr.sin_port = htons(session->port); addr.sin_port = htons(session->port);
#ifdef __CYGWIN__
rc = inet_aton(session->hostname, &addr.sin_addr);
#else
rc = inet_pton(AF_INET, session->hostname, &addr.sin_addr); rc = inet_pton(AF_INET, session->hostname, &addr.sin_addr);
#endif
if (rc <= 0) { if (rc <= 0) {
struct hostent *host = gethostbyname(session->hostname); struct hostent *host = gethostbyname(session->hostname);
if (host == NULL) { if (host == NULL) {
@ -2935,6 +3090,7 @@ ipmi_lanplus_open(struct ipmi_intf * intf)
intf->opened = 1; intf->opened = 1;
/* /*
* *
* Make sure the BMC supports IPMI v2 / RMCP+ * Make sure the BMC supports IPMI v2 / RMCP+
@ -2974,6 +3130,7 @@ ipmi_lanplus_open(struct ipmi_intf * intf)
goto fail; goto fail;
} }
/* /*
* RAKP 3 * RAKP 3
*/ */
@ -3056,8 +3213,8 @@ void test_crypt2()
char encrypt_buffer[1000]; char encrypt_buffer[1000];
char decrypt_buffer[1000]; char decrypt_buffer[1000];
int bytes_encrypted; uint32_t bytes_encrypted;
int bytes_decrypted; uint32_t bytes_decrypted;
printbuf(data, strlen(data), "input data"); printbuf(data, strlen(data), "input data");

View File

@ -80,23 +80,6 @@
#define IPMI_PRIV_OEM 5 #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 #define IPMI_CRYPT_AES_CBC_128_BLOCK_SIZE 0x10
@ -115,7 +98,7 @@
* TODO: these are wild guesses and should be checked * TODO: these are wild guesses and should be checked
*/ */
#define IPMI_MAX_CONF_HEADER_SIZE 0x20 #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_CONF_TRAILER_SIZE 0x20
#define IPMI_MAX_INTEGRITY_PAD_SIZE 0x20 #define IPMI_MAX_INTEGRITY_PAD_SIZE 0x20
#define IPMI_MAX_AUTH_CODE_SIZE 0x20 #define IPMI_MAX_AUTH_CODE_SIZE 0x20
@ -129,7 +112,7 @@
* one integrity algorithm, and 1 encyrption alogrithm * one integrity algorithm, and 1 encyrption alogrithm
*/ */
#define IPMI_OPEN_SESSION_REQUEST_SIZE 32 #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_RAKP3_MESSAGE_MAX_SIZE 28
#define IPMI_MAX_USER_NAME_LENGTH 16 #define IPMI_MAX_USER_NAME_LENGTH 16

View File

@ -71,12 +71,13 @@
* 1 on failure (the authcode does not match) * 1 on failure (the authcode does not match)
*/ */
int lanplus_rakp2_hmac_matches(const struct ipmi_session * session, 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; char * buffer;
int bufferLength, i; int bufferLength, i;
uint8_t mac[20]; uint8_t mac[20];
int macLength; uint32_t macLength;
uint32_t SIDm_lsbf, SIDc_lsbf; 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) if (session->v2_data.auth_alg == IPMI_AUTH_RAKP_NONE)
return 1; 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); assert(session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_SHA1);
@ -167,19 +168,17 @@ int lanplus_rakp2_hmac_matches(const struct ipmi_session * session,
printbuf((char*)(session->authcode), IPMI_AUTHCODE_BUFFER_SIZE, ">> rakp2 mac key"); printbuf((char*)(session->authcode), IPMI_AUTHCODE_BUFFER_SIZE, ">> rakp2 mac key");
} }
/* /*
* The buffer is complete. Let's hash. * The buffer is complete. Let's hash.
*/ */
lanplus_HMAC(session->v2_data.auth_alg, lanplus_HMAC(session->v2_data.auth_alg,
session->authcode, session->authcode,
(session->authcode[IPMI_AUTHCODE_BUFFER_SIZE] == 0? IPMI_AUTHCODE_BUFFER_SIZE,
strlen(session->authcode): IPMI_AUTHCODE_BUFFER_SIZE),
buffer, buffer,
bufferLength, bufferLength,
mac, mac,
&macLength); &macLength);
free(buffer); free(buffer);
@ -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. * If the authentication algorithm is IPMI_AUTH_RAKP_NONE, we return success.
* *
* return 0 on success (the authcode matches) * return 1 on success (the authcode matches)
* 1 on failure (the authcode does not match) * 0 on failure (the authcode does not match)
*
*/ */
int lanplus_rakp4_hmac_matches(const struct ipmi_session * session, 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; char * buffer;
int bufferLength, i; int bufferLength, i;
uint8_t mac[20]; uint8_t mac[20];
int macLength; uint32_t macLength;
uint32_t SIDc_lsbf; uint32_t SIDc_lsbf;
if (session->v2_data.auth_alg == IPMI_AUTH_RAKP_NONE) if (ipmi_oem_active(intf, "intelplus")){
return 1; /* Intel BMC responds with the integrity Algorithm in RAKP4 */
if (session->v2_data.integrity_alg == IPMI_INTEGRITY_NONE)
/* We don't yet support other alogrithms */ return 1;
assert(session->v2_data.auth_alg == IPMI_INTEGRITY_HMAC_SHA1_96);
/* 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 algorithms */
assert(session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_SHA1);
}
bufferLength = bufferLength =
16 + /* Rm */ 16 + /* Rm */
@ -285,9 +295,11 @@ int lanplus_rakp4_hmac_matches(const struct ipmi_session * session,
/* /*
* The buffer is complete. Let's hash. * 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, session->v2_data.sik,
20, IPMI_SIK_BUFFER_SIZE,
buffer, buffer,
bufferLength, bufferLength,
mac, mac,
@ -295,7 +307,8 @@ int lanplus_rakp4_hmac_matches(const struct ipmi_session * session,
if (verbose > 2) if (verbose > 2)
{ {
printbuf(mac, macLength, ">> rakp4 mac as computed by the remote console"); 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, int lanplus_generate_rakp3_authcode(char * output_buffer,
const struct ipmi_session * session, const struct ipmi_session * session,
uint32_t * mac_length) uint32_t * mac_length,
struct ipmi_intf * intf)
{ {
int ret = 0; int ret = 0;
int input_buffer_length, i; int input_buffer_length, i;
@ -346,7 +360,7 @@ int lanplus_generate_rakp3_authcode(char * output_buffer,
return 0; 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); assert(session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_SHA1);
input_buffer_length = input_buffer_length =
@ -384,7 +398,10 @@ int lanplus_generate_rakp3_authcode(char * output_buffer,
memcpy(input_buffer + 16, &SIDm_lsbf, 4); memcpy(input_buffer + 16, &SIDm_lsbf, 4);
/* ROLEm */ /* ROLEm */
input_buffer[20] = session->v2_data.requested_role; if (ipmi_oem_active(intf, "intelplus"))
input_buffer[20] = session->privlvl;
else
input_buffer[20] = session->v2_data.requested_role;
/* ULENGTHm */ /* ULENGTHm */
input_buffer[21] = strlen(session->username); input_buffer[21] = strlen(session->username);
@ -399,11 +416,9 @@ int lanplus_generate_rakp3_authcode(char * output_buffer,
printbuf((char*)(session->authcode), IPMI_AUTHCODE_BUFFER_SIZE, ">> rakp3 mac key"); printbuf((char*)(session->authcode), IPMI_AUTHCODE_BUFFER_SIZE, ">> rakp3 mac key");
} }
lanplus_HMAC(session->v2_data.auth_alg, lanplus_HMAC(session->v2_data.auth_alg,
session->authcode, session->authcode,
(session->authcode[IPMI_AUTHCODE_BUFFER_SIZE - 1] == 0? IPMI_AUTHCODE_BUFFER_SIZE,
strlen(session->authcode): IPMI_AUTHCODE_BUFFER_SIZE),
input_buffer, input_buffer,
input_buffer_length, input_buffer_length,
output_buffer, output_buffer,
@ -451,8 +466,7 @@ int lanplus_generate_sik(struct ipmi_session * session)
char * input_buffer; char * input_buffer;
int input_buffer_length, i; int input_buffer_length, i;
char * input_key; char * input_key;
int input_key_length; uint32_t mac_length;
int mac_length;
memset(session->v2_data.sik, 0, IPMI_SIK_BUFFER_SIZE); 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) if (session->v2_data.auth_alg == IPMI_AUTH_RAKP_NONE)
return 0; 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); assert(session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_SHA1);
input_buffer_length = input_buffer_length =
@ -522,20 +536,20 @@ int lanplus_generate_sik(struct ipmi_session * session)
assert(0); assert(0);
input_key = session->v2_data.kg; input_key = session->v2_data.kg;
input_key_length = strlen(session->v2_data.kg);
} }
else else
{ {
/* We will be hashing with Kuid */ /* We will be hashing with Kuid */
input_key = session->authcode; 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, lanplus_HMAC(session->v2_data.auth_alg,
input_key, input_key,
input_key_length, IPMI_AUTHCODE_BUFFER_SIZE,
input_buffer, input_buffer,
input_buffer_length, input_buffer_length,
session->v2_data.sik, session->v2_data.sik,
@ -583,7 +597,7 @@ int lanplus_generate_k1(struct ipmi_session * session)
{ {
lanplus_HMAC(session->v2_data.auth_alg, lanplus_HMAC(session->v2_data.auth_alg,
session->v2_data.sik, session->v2_data.sik,
20, /* SIK length */ IPMI_SIK_BUFFER_SIZE, /* SIK length */
CONST_1, CONST_1,
20, 20,
session->v2_data.k1, session->v2_data.k1,
@ -626,7 +640,7 @@ int lanplus_generate_k2(struct ipmi_session * session)
{ {
lanplus_HMAC(session->v2_data.auth_alg, lanplus_HMAC(session->v2_data.auth_alg,
session->v2_data.sik, session->v2_data.sik,
20, /* SIK length */ IPMI_SIK_BUFFER_SIZE, /* SIK length */
CONST_2, CONST_2,
20, 20,
session->v2_data.k2, session->v2_data.k2,
@ -675,7 +689,6 @@ int lanplus_encrypt_payload(uint8_t crypt_alg,
if (crypt_alg == IPMI_CRYPT_NONE) if (crypt_alg == IPMI_CRYPT_NONE)
{ {
lprintf(LOG_WARNING, "NOT ENCRYPTING");
/* Just copy the input to the output */ /* Just copy the input to the output */
*bytes_written = input_length; *bytes_written = input_length;
return 0; return 0;
@ -683,7 +696,7 @@ int lanplus_encrypt_payload(uint8_t crypt_alg,
/* Currently, we only support AES */ /* Currently, we only support AES */
assert(crypt_alg == IPMI_CRYPT_AES_CBC_128); assert(crypt_alg == IPMI_CRYPT_AES_CBC_128);
assert(input_length <= 255); assert(input_length <= IPMI_MAX_PAYLOAD_SIZE);
/* /*
@ -786,7 +799,7 @@ int lanplus_has_valid_auth_code(struct ipmi_rs * rs,
lanplus_HMAC(session->v2_data.integrity_alg, lanplus_HMAC(session->v2_data.integrity_alg,
session->v2_data.k1, session->v2_data.k1,
20, IPMI_AUTHCODE_BUFFER_SIZE,
rs->data + IMPI_LANPLUS_OFFSET_AUTHTYPE, rs->data + IMPI_LANPLUS_OFFSET_AUTHTYPE,
rs->data_len - IMPI_LANPLUS_OFFSET_AUTHTYPE - IPMI_SHA1_AUTHCODE_SIZE, rs->data_len - IMPI_LANPLUS_OFFSET_AUTHTYPE - IPMI_SHA1_AUTHCODE_SIZE,
generated_authcode, generated_authcode,

View File

@ -41,15 +41,20 @@
/* /*
* See the implementation file for documentation * 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, 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, 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, int lanplus_generate_rakp3_authcode(char * buffer,
const struct ipmi_session * session, 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_sik(struct ipmi_session * session);
int lanplus_generate_k1(struct ipmi_session * session); int lanplus_generate_k1(struct ipmi_session * session);
int lanplus_generate_k2(struct ipmi_session * session); int lanplus_generate_k2(struct ipmi_session * session);

View File

@ -34,6 +34,7 @@
* facility. * facility.
*/ */
#include "ipmitool/ipmi_constants.h"
#include "lanplus.h" #include "lanplus.h"
#include "lanplus_crypt_impl.h" #include "lanplus_crypt_impl.h"
#include <openssl/hmac.h> #include <openssl/hmac.h>
@ -79,7 +80,7 @@ int lanplus_seed_prng(uint32_t bytes)
int int
lanplus_rand(uint8_t * buffer, uint32_t num_bytes) 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 #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,7 +163,8 @@ lanplus_encrypt_aes_cbc_128(const uint8_t * iv,
EVP_CIPHER_CTX ctx; EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx); EVP_CIPHER_CTX_init(&ctx);
EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key, iv); EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key, iv);
EVP_CIPHER_CTX_set_padding(&ctx, 0);
*bytes_written = 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); 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 */ /* Error */
*bytes_written = 0; *bytes_written = 0;
@ -195,7 +197,7 @@ lanplus_encrypt_aes_cbc_128(const uint8_t * iv,
{ {
uint32_t tmplen; 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; *bytes_written = 0;
return; /* Error */ return; /* Error */
@ -236,6 +238,8 @@ lanplus_decrypt_aes_cbc_128(const uint8_t * iv,
EVP_CIPHER_CTX ctx; EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx); EVP_CIPHER_CTX_init(&ctx);
EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key, iv); EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key, iv);
EVP_CIPHER_CTX_set_padding(&ctx, 0);
if (verbose > 2) 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); 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 */ /* Error */
fprintf(stderr, "ERROR: decrypt update failed"); fprintf(stderr, "ERROR: decrypt update failed");
@ -270,7 +274,7 @@ lanplus_decrypt_aes_cbc_128(const uint8_t * iv,
{ {
uint32_t tmplen; 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]; char buffer[1000];
ERR_error_string(ERR_get_error(), buffer); ERR_error_string(ERR_get_error(), buffer);

View File

@ -43,10 +43,13 @@ extern const struct valstr ipmi_auth_algorithms[];
extern const struct valstr ipmi_integrity_algorithms[]; extern const struct valstr ipmi_integrity_algorithms[];
extern const struct valstr ipmi_encryption_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) void lanplus_dump_open_session_response(const struct ipmi_rs * rsp)
{ {
if (verbose < 2)
return;
printf("%sOPEN SESSION RESPONSE\n", DUMP_PREFIX_INCOMING); printf("%sOPEN SESSION RESPONSE\n", DUMP_PREFIX_INCOMING);
printf("%s Message tag : 0x%02x\n", 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", printf("%s Console Session ID : 0x%08lx\n",
DUMP_PREFIX_INCOMING, DUMP_PREFIX_INCOMING,
(long)rsp->payload.open_session_response.console_id); (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", printf("%s BMC Session ID : 0x%08lx\n",
DUMP_PREFIX_INCOMING, DUMP_PREFIX_INCOMING,
(long)rsp->payload.open_session_response.bmc_id); (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; int i;
if (verbose < 2)
return;
printf("%sRAKP 2 MESSAGE\n", DUMP_PREFIX_INCOMING); printf("%sRAKP 2 MESSAGE\n", DUMP_PREFIX_INCOMING);
printf("%s Message tag : 0x%02x\n", 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; int i;
if (verbose < 2)
return;
printf("%sRAKP 4 MESSAGE\n", DUMP_PREFIX_INCOMING); printf("%sRAKP 4 MESSAGE\n", DUMP_PREFIX_INCOMING);
printf("%s Message tag : 0x%02x\n", printf("%s Message tag : 0x%02x\n",
DUMP_PREFIX_INCOMING, DUMP_PREFIX_INCOMING,
rsp->payload.rakp2_message.message_tag); rsp->payload.rakp4_message.message_tag);
printf("%s RMCP+ status : %s\n", printf("%s RMCP+ status : %s\n",
DUMP_PREFIX_INCOMING, DUMP_PREFIX_INCOMING,
val2str(rsp->payload.rakp2_message.rakp_return_code, val2str(rsp->payload.rakp4_message.rakp_return_code,
ipmi_rakp_return_codes)); ipmi_rakp_return_codes));
printf("%s Console Session ID : 0x%08lx\n", printf("%s Console Session ID : 0x%08lx\n",
DUMP_PREFIX_INCOMING, DUMP_PREFIX_INCOMING,
(long)rsp->payload.rakp2_message.console_id); (long)rsp->payload.rakp4_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");
switch(auth_alg) switch(auth_alg)
{ {

View File

@ -1,4 +1,5 @@
#include "lanplus.h" #include "lanplus.h"
#include "ipmitool/ipmi_constants.h"
const struct valstr ipmi_rakp_return_codes[] = { 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_INVALID_NAME_LENGTH, "invalid name length" },
{ IPMI_RAKP_STATUS_UNAUTHORIZED_NAME, "unauthorized name" }, { IPMI_RAKP_STATUS_UNAUTHORIZED_NAME, "unauthorized name" },
{ IPMI_RAKP_STATUS_UNAUTHORIZED_GUID, "unauthorized GUID" }, { 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_INVALID_CONFIDENTIALITY_ALGORITHM, "invalid confidentiality algorithm" },
{ IPMI_RAKP_STATUS_NO_CIPHER_SUITE_MATCH, "no matching cipher suite" }, { IPMI_RAKP_STATUS_NO_CIPHER_SUITE_MATCH, "no matching cipher suite" },
{ IPMI_RAKP_STATUS_ILLEGAL_PARAMTER, "illegal parameter" }, { 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 },
};