Compare commits

...

191 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
ada87b8255 send lprintf messages to stderr 2005-01-11 21:36:37 +00:00
81d5b08b3d send warning to stderr 2005-01-11 21:36:22 +00:00
08844ec93b add function comments 2005-01-11 16:16:43 +00:00
218094310b display only command list when 'help' specified on command line 2005-01-11 16:08:38 +00:00
38fc65ae88 beautify lan print output 2005-01-11 16:08:12 +00:00
777cdb124c fix lan parameter set where it was doing incorrect comparison on channel medium 2005-01-10 20:25:34 +00:00
eb75ecf114 the option to read password from file is available on solaris 2005-01-10 17:22:52 +00:00
264a45de0f add attribution 2005-01-08 03:00:23 +00:00
704f4c87c6 update changelog 2005-01-08 02:58:33 +00:00
c7a6be575d add more flexible way of handling OEM boards
now pass a "-o <oemtype>" argument on the command line
the currently defined oem types are "supermicro" and "intelwv2"
the existing -g and -s options are still present for compatibility
2005-01-08 02:49:22 +00:00
f763641c2e only enable "shell" command if readline is found 2005-01-07 23:39:15 +00:00
5575a33119 set hard limit of 128 in nested structure for older gcc 2005-01-07 23:31:12 +00:00
dd376289c5 fix newline on solaris 2005-01-07 23:29:49 +00:00
9c160b5a07 add BMC plugin for Solaris 10 2005-01-07 22:57:15 +00:00
46f3f3d4db return value for non-void function, for -Wall compile 2005-01-07 22:55:55 +00:00
ad932e0cfd fix datatypes so it compiles with -Wall 2005-01-07 22:54:22 +00:00
b5306e1aa6 add unused attribute to static definitions so it compiles with -Wall 2005-01-07 22:53:55 +00:00
e72103d30f check malloc and strdup for success 2005-01-07 22:43:38 +00:00
21837864cc send errors to stderr using lprintf helper 2005-01-07 22:37:58 +00:00
cfa8f69f97 send errors to stderr using lprintf helper 2005-01-07 22:28:18 +00:00
55969d4a32 change return types 2005-01-07 22:17:25 +00:00
87234ecd0f send errors to stderr,
propogate return codes to top level
2005-01-07 22:15:56 +00:00
14ee3f2362 be pedantic when checking for errors 2005-01-07 22:14:56 +00:00
db9614572b send errors to stderr 2005-01-07 22:14:30 +00:00
014040610f use uint{8,16,32}_t instead of "unsigned {char,short,int|long}" 2005-01-07 02:05:49 +00:00
9c848916cc fix compile problems with -g
update lan interface to send debug and errors to stderr
2005-01-06 22:35:35 +00:00
de7de91f99 use uint8_t and uint32_t throughout ipmitool 2005-01-06 22:32:07 +00:00
dbbeee1b6f update error handling for "session" and "user" commands
check channel medium type before attempting to do lan operations on it
2005-01-06 21:17:52 +00:00
32cba5f174 don't bail on SDR version 0x02 2005-01-06 19:19:35 +00:00
f5c8042629 remove the rest of isol 2005-01-06 19:13:52 +00:00
e23dde507e remove isol,
remove signal handler function as it was not used,
clean up error handling in ipmi_open_file
change min define to __min to avoid conflicts
2005-01-06 19:09:05 +00:00
4db9739e17 massive rework of many subsytems
handle errors better and return status codes correctly
2005-01-06 17:48:24 +00:00
b6852fc77b fix supermicro sdr problem 2004-12-13 19:53:46 +00:00
356fad232e formatting changes 2004-11-24 23:53:19 +00:00
30bc6b18cb change bmc -> mc 2004-11-24 23:52:23 +00:00
3dfa1a4209 fix handling of signed equation variables in sensor readings 2004-11-24 23:23:04 +00:00
d25bd0a5e7 rename bmc -> mc 2004-11-22 21:34:30 +00:00
0007006347 use helper function for printing discrete states 2004-11-19 19:53:09 +00:00
7dcd5cec76 add function to print extended SEL record info
for breaking down Event Data fields
2004-11-19 19:52:15 +00:00
929d330424 add function to handle printing asserted states 2004-11-19 19:51:16 +00:00
d17909e3ec check sizes before malloc,
change strcpy to strncpy
2004-11-19 19:50:19 +00:00
2e46c84218 only search for 7 bits 2004-11-19 19:49:23 +00:00
b0ccfba549 moved completion_code_vals 2004-11-19 19:48:53 +00:00
49cc30816a add missing header 2004-11-19 19:48:16 +00:00
f4e4d8433c clean up a few state descriptions 2004-11-19 19:47:02 +00:00
a718edf808 add function for printing discrete states 2004-11-19 19:46:27 +00:00
dce547bcfd put completion_code_vals define back in here 2004-11-19 19:45:44 +00:00
f045c0fa3d add much improved startup script for redhat
rename old script to ipmi.init.basic
2004-11-17 23:48:44 +00:00
c58b02fa94 fix for systems where ipv6 is enabled 2004-11-17 23:47:49 +00:00
ae735c748d set my_addr to IPMI_BMC_SLAVE_ADDR by default 2004-11-17 23:36:06 +00:00
dba187190f fix compile on freebsd 2004-11-17 23:35:24 +00:00
914159b3b5 handle bridged reponses by matching the request and response commands
don't send pings to sm boards
2004-11-17 23:34:29 +00:00
33d9b75951 change "bmc" top level command to "ipmc"
but keep "bmc" around for compatibility (for now)
2004-11-17 23:33:35 +00:00
a5012d1901 make readline use handle different versions 2004-11-17 23:27:54 +00:00
1a34cc960e add cleanup function to clear sdr cache,
zero password field when setting
2004-11-17 23:27:13 +00:00
2e1f1ef750 fix compile on freebsd 2004-11-17 23:25:16 +00:00
17b43f1b45 add new valstrs 2004-11-17 23:23:05 +00:00
0aba9fc8b6 change formatting to be consistant 2004-11-17 23:21:48 +00:00
279053aa84 add a "sel get" command,
change formatting to be consistant
2004-11-17 23:20:22 +00:00
3c58698736 change formating to be consistant,
add entity lookup functions
2004-11-17 23:19:10 +00:00
d23d74ce9f fix typo 2004-11-17 23:17:54 +00:00
a87957ac7f handle errors gracefully,
check values before malloc,
add external function for entity association lookups
2004-11-17 23:16:44 +00:00
7723fb41b3 add support for reading event list from a text file,
add support for generating events over system interface
2004-11-17 23:14:46 +00:00
6cdcd8555a break down ccode on error 2004-11-17 23:11:59 +00:00
1cf302c89e move valstr defines 2004-11-17 23:10:56 +00:00
b696e2ceb3 add new valstr defines 2004-11-17 23:02:19 +00:00
9ec6a6d154 use entity_id structure,
add oem structure,
move valstr defines to ipmi_string.h
2004-11-17 23:01:51 +00:00
66fbb6fbbc move valstr defines to ipmi_string.h 2004-11-17 22:59:54 +00:00
4e7e7ae0a6 add cleanup function 2004-11-17 22:59:26 +00:00
79f3994cfb move completion_code_vals define to ipmi_strings.h 2004-11-17 22:58:14 +00:00
e7e901c935 add functions for SDR to use 2004-11-17 22:56:50 +00:00
3836cb00e8 move valstr defines to ipmi_strings.h 2004-11-17 22:51:30 +00:00
d52c8f01c5 move strings to lib/ipmi_strings.h
add entity id structure for lookups
2004-11-17 22:19:15 +00:00
c3df0b8851 fix for freebsd 2004-11-17 22:16:23 +00:00
99320869d2 move include 2004-11-11 20:49:43 +00:00
1f36312b41 fix spelling error 2004-11-11 20:29:15 +00:00
62574d281c fix formatting 2004-11-11 19:13:31 +00:00
e75fb44b4c fix spelling errors 2004-11-11 19:12:39 +00:00
848646514c check for both curses and ncurses 2004-11-11 19:07:45 +00:00
4edd58a744 fix compile on freebsd 2004-10-25 19:37:38 +00:00
2d3af919ba add special auth support 2004-10-25 19:21:51 +00:00
2c189f0663 add special auth functions 2004-10-25 19:21:13 +00:00
a3a95fb770 add support for -s option 2004-10-25 19:20:47 +00:00
5c846a6eb6 allow oem authtype to be set 2004-10-25 19:20:21 +00:00
3ebe119a94 add authspecial flag 2004-10-25 19:19:59 +00:00
b49691a272 add pef header to cvs 2004-10-25 19:19:39 +00:00
0ef81e301f add pef support, from Tim Murphy 2004-10-08 22:41:38 +00:00
c5d65ba940 update version to 1.6.2 2004-10-08 22:17:11 +00:00
b60c6cea30 update version to 1.6.1 2004-10-08 22:13:09 +00:00
c72e3333eb add Percent Used column to sel info display 2004-10-08 02:52:30 +00:00
ac931daa86 Added a subcommand for testing password (as well as password length per v.2).
Also re-tabified.
2004-10-01 15:24:45 +00:00
3d4acbd829 allow twenty byte passwords 2004-10-01 15:17:48 +00:00
3d790edc6e allow configuring SOL to 9600 bps 2004-09-30 21:37:43 +00:00
4e025b3e0e fix handling of bad SEL entries 2004-09-24 18:21:12 +00:00
62f52f0598 add option to disable libcrypto use for md2/md5 2004-09-20 17:55:51 +00:00
f874a93ccb string compare interface name length fix 2004-09-20 16:41:35 +00:00
1f7ba3dd66 fix intermittant segfault setting lan parameters 2004-09-20 16:40:54 +00:00
e298b0b99f Update name of interface (intf_lanpus ==> lanplus) for check 2004-09-15 15:12:52 +00:00
79 changed files with 12002 additions and 5423 deletions

View File

@ -1,3 +1,31 @@
version 1.8.0
* Fix IPMIv2.0 issues
* Fix chassis boot parameter support
* Add support for linear sensors
version 1.7.1
* Update bmc plugin to work with new Solaris bmc driver (new ioctl
for interface detection and new STREAMS message-based interface)
version 1.7.0
* Propogate errors correctly so exit status will be useful
* More consistent display of errors including completion code text
* 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
version 1.6.2
* Support for Supermicro BMC OEM authentication method
version 1.6.1
* Fix minor problem with LAN parameter setting
version 1.6.0
* Add a README file
* Add Solaris x86 interface plugin

View File

@ -176,7 +176,6 @@ Commands:
fru Print built-in FRU and scan SDR for FRU locators
sel Print System Evelnt Log
sol Configure IPMIv2.0 Serial-over-LAN
isol Configure Intel IPMIv1.5 Serial-over-LAN
user Configure BMC users
channel Configure BMC channels
session Print session information

View File

@ -3,7 +3,7 @@ dnl autoconf for ipmitool
dnl
AC_INIT([src/ipmitool.c])
AC_CANONICAL_SYSTEM
AM_INIT_AUTOMAKE([ipmitool], [1.6.0])
AM_INIT_AUTOMAKE([ipmitool], [1.8.0])
AM_CONFIG_HEADER(config.h)
AC_CONFIG_SRCDIR([src/ipmitool.c])
AC_PREREQ(2.50)
@ -58,12 +58,38 @@ solaris*)
STRIP=gstrip
LD=gld
AR=gar
# openssl libs are in /usr/sfw/lib on solaris 10
LIBS="$LIBS -R/usr/sfw/lib"
# disable the linux-specific interfaces
# and bmc on SPARC (there is no bmc driver for SPARC)
if [[ `mach -p` = sparc ]]; then
enable_intf_bmc=no
else
enable_intf_bmc=yes
fi
enable_intf_imb=no
enable_intf_open=no
enable_ipmievd=no
enable_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
AC_SUBST(ARCH, $host_cpu)
@ -72,25 +98,33 @@ AC_SUBST(PSTAMP, $host)
AC_SUBST(BASEDIR, $prefix)
dnl check for OpenSSL functionality
AC_ARG_ENABLE([internal-md5],
[AC_HELP_STRING([--enable-internal-md5],
[enable internal MD5 library [default=no]])],
[], [enable_internal_md5=no])
AC_CHECK_LIB([crypto], [EVP_aes_128_cbc],
[have_crypto=yes; LIBS="$LIBS -lcrypto"],
[have_crypto=no], [-lcrypto])
[if test "x$enable_internal_md5" != "xyes"; then
have_crypto=yes; LIBS="$LIBS -lcrypto"
fi], [have_crypto=no], [-lcrypto])
AC_CHECK_LIB([crypto], [MD5_Init],
[if test "x$have_crypto" != "xyes"; then
LIBS="$LIBS -lcrypto"
have_md5=yes
fi
AC_DEFINE(HAVE_CRYPTO_MD5, [1], [Define to 1 if libcrypto supports MD5.])],
[], [-lcrypto])
[if test "x$enable_internal_md5" != "xyes"; then
if test "x$have_crypto" != "xyes"; then
LIBS="$LIBS -lcrypto"
have_md5=yes
fi
AC_DEFINE(HAVE_CRYPTO_MD5, [1], [Define to 1 if libcrypto supports MD5.])
fi], [], [-lcrypto])
AC_CHECK_LIB([crypto], [MD2_Init],
[if test "x$have_crypto" != "xyes" && test "x$have_md5" != "xyes"; then
LIBS="$LIBS -lcrypto"
have_md2=yes
fi
AC_DEFINE(HAVE_CRYPTO_MD2, [1], [Define to 1 if libcrypto supports MD2.])],
[], [-lcrypto])
[if test "x$enable_internal_md5" != "xyes"; then
if test "x$have_crypto" != "xyes" && test "x$have_md5" != "xyes"; then
LIBS="$LIBS -lcrypto"
have_md2=yes
fi
AC_DEFINE(HAVE_CRYPTO_MD2, [1], [Define to 1 if libcrypto supports MD2.])
fi], [], [-lcrypto])
dnl enable IPMIv1.5 LAN interface
AC_ARG_ENABLE([intf-lan],
@ -124,6 +158,8 @@ if test "x$enable_intf_lanplus" = "xyes"; then
AC_SUBST(INTF_LANPLUS, [lanplus])
AC_SUBST(INTF_LANPLUS_LIB, [libintf_lanplus.la])
IPMITOOL_INTF_LIB="$IPMITOOL_INTF_LIB lanplus/libintf_lanplus.la"
else
enable_intf_lanplus=no
fi
dnl look for OpenIPMI header files
@ -151,7 +187,7 @@ AC_CHECK_HEADER([linux/ipmi.h],
dnl enable Linux OpenIPMI interface
AC_ARG_ENABLE([intf-open],
[AC_HELP_STRING([--enable-intf-open],
[enable Linux OpenIPMI interface [default=yes]])],
[enable Linux OpenIPMI interface [default=auto]])],
[], [enable_intf_open=yes])
if test "x$enable_intf_open" = "xstatic" || test "x$enable_intf_open" = "xplugin"; then
enable_intf_open=yes
@ -166,7 +202,7 @@ fi
dnl enable Intel IMB interface
AC_ARG_ENABLE([intf-imb],
[AC_HELP_STRING([--enable-intf-imb],
[enable Intel IMB driver interface [default=yes]])],
[enable Intel IMB driver interface [default=auto]])],
[], [enable_intf_imb=yes])
if test "x$enable_intf_imb" = "xstatic" || test "x$enable_intf_imb" = "xplugin"; then
enable_intf_imb=yes
@ -182,42 +218,56 @@ dnl enable Solaris LIPMI interface
AC_CHECK_HEADER([sys/lipmi/lipmi_intf.h], [have_lipmi=yes], [have_lipmi=no])
AC_ARG_ENABLE([intf-lipmi],
[AC_HELP_STRING([--enable-intf-lipmi],
[enable Solaris x86 IPMI interface [default=auto]])],
[enable Solaris 9 x86 IPMI interface [default=no]])],
[if test "x$enable_intf_lipmi" != "xno" && test "x$have_lipmi" != "xyes"; then
echo "** Unable to build Solaris x86 IPMI interface support!"
echo "** Unable to build Solaris 9 x86 IPMI interface support!"
enable_intf_lipmi=no
fi],
[enable_intf_lipmi=$have_lipmi])
[enable_intf_lipmi=no])
if test "x$enable_intf_lipmi" = "xstatic" || test "x$enable_intf_lipmi" = "xplugin"; then
enable_intf_lipmi=yes
fi
if test "x$enable_intf_lipmi" = "xyes"; then
AC_DEFINE(IPMI_INTF_LIPMI, [1], [Define to 1 to enable Solaris LIPMI interface.])
AC_DEFINE(IPMI_INTF_LIPMI, [1], [Define to 1 to enable Solaris 9 LIPMI interface.])
AC_SUBST(INTF_LIPMI, [lipmi])
AC_SUBST(INTF_LIPMI_LIB, [libintf_lipmi.la])
IPMITOOL_INTF_LIB="$IPMITOOL_INTF_LIB lipmi/libintf_lipmi.la"
fi
dnl enable Solaris BMC interface
AC_ARG_ENABLE([intf-bmc],
[AC_HELP_STRING([--enable-intf-bmc],
[enable Solaris 10 x86 IPMI interface [default=auto]])],,
[enable_intf_bmc=no])
if test "x$enable_intf_bmc" = "xstatic" || test "x$enable_intf_bmc" = "xplugin"; then
enable_intf_bmc=yes
fi
if test "x$enable_intf_bmc" = "xyes"; then
AC_DEFINE(IPMI_INTF_BMC, [1], [Define to 1 to enable Solaris 10 BMC interface.])
AC_SUBST(INTF_BMC, [bmc])
AC_SUBST(INTF_BMC_LIB, [libintf_bmc.la])
IPMITOOL_INTF_LIB="$IPMITOOL_INTF_LIB bmc/libintf_bmc.la"
fi
AC_SUBST(IPMITOOL_INTF_LIB)
dnl check for readline library to enable ipmi shell
have_readline=no
AC_SEARCH_LIBS([readline], [readline], [have_readline=yes],
[AC_CHECK_LIB([readline], [readline],
[have_readline=yes], [], [-lcurses])])
AC_ARG_ENABLE([ipmishell],
[AC_HELP_STRING([--enable-ipmishell],
[enable IPMI shell interface [default=yes]])],
[], [enable_ipmishell=yes])
if test "x$enable_ipmishell" = "xyes" && test "x$have_readline" = "xyes"; then
AC_DEFINE(HAVE_READLINE, [1], [Define to 1 if readline present.])
LIBS="$LIBS -lcurses -lreadline"
if test "x$enable_ipmishell" = "xyes"; then
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
AC_DEFINE(HAVE_READLINE, [1], [Define to 1 if readline present.])
fi
fi
dnl enable IPMI Event Daemon
AC_ARG_ENABLE([ipmievd],
[AC_HELP_STRING([--enable-ipmievd],
[enable IPMI Event daemon [default=yes]])],
[enable IPMI Event daemon [default=auto]])],
[], [enable_ipmievd=yes])
AM_CONDITIONAL(IPMIEVD, [test "x$enable_ipmievd" = "xyes"])
if test "x$enable_ipmievd" = "xyes"; then
@ -251,6 +301,7 @@ AC_CONFIG_FILES([Makefile
src/plugins/lanplus/Makefile
src/plugins/open/Makefile
src/plugins/imb/Makefile
src/plugins/bmc/Makefile
src/plugins/lipmi/Makefile])
AC_OUTPUT
@ -263,6 +314,7 @@ AC_MSG_RESULT([ lan : $enable_intf_lan])
AC_MSG_RESULT([ lanplus : $enable_intf_lanplus])
AC_MSG_RESULT([ open : $enable_intf_open])
AC_MSG_RESULT([ imb : $enable_intf_imb])
AC_MSG_RESULT([ bmc : $enable_intf_bmc])
AC_MSG_RESULT([ lipmi : $enable_intf_lipmi])
AC_MSG_RESULT([])
AC_MSG_RESULT([Extra tools])

View File

@ -34,6 +34,7 @@
MAINTAINERCLEANFILES = Makefile.in
dist_pkgdata_DATA = bmclanconf ipmi.init README \
dist_pkgdata_DATA = bmclanconf README \
ipmi.init.basic ipmi.init.redhat \
collect_data.sh create_rrds.sh create_webpage_compact.sh create_webpage.sh

View File

@ -248,7 +248,7 @@ case `uname -s` in
Linux)
if [ X$IFACE != X ]; then
if [ X$IP_ADDRESS = X ]; then
IP_ADDRESS=`$IFCONFIG $IFACE | grep inet | awk -F"[:[:space:]]+" '{print $4}'`
IP_ADDRESS=`$IFCONFIG $IFACE | grep "inet addr" | awk -F"[:[:space:]]+" '{print $4}'`
fi
if [ X$IP_NETMASK = X ]; then
IP_NETMASK=`$IFCONFIG $IFACE | grep Bcast | awk -F"[:[:space:]]+" '{print $8}'`

216
ipmitool/contrib/ipmi.init.redhat Executable file
View File

@ -0,0 +1,216 @@
#!/bin/sh
#
# chkconfig: 2345 11 60
# description: start, stop, or query ipmi system monitoring tools
# config: /etc/sysconfig/ipmi
#
# For Redhat, Fedora, or similar systems. Handles both 2.4 and 2.6
# configurations. Requires an /etc/sysconfig/ipmi file to function,
# see below.
#
# Phil Hollenback
# philiph@pobox.com
# Source function library.
. /etc/init.d/functions
# Exit silently if we don't have a sysconfig file,
# and read IPMI setting from it to determine whether or
# not to continue.
# The only current setting is ipmi={YES|NO}, whether or not
# to enable IPMI.
[ -f /etc/sysconfig/ipmi ] || exit 0
. /etc/sysconfig/ipmi
[ "${IPMI}" = "yes" ] || exit 0
RETVAL=0
start() {
echo -n $"Starting ipmi: "
# If ipmidev isn't listed in /proc/devices, try
# loading the modules.
if ! grep -q ipmidev /proc/devices
then
/sbin/modprobe ipmi_msghandler || RETVAL=1
/sbin/modprobe ipmi_devintf || RETVAL=1
# Try loading new driver module, fall back to old
# module if that fails.
if ! /sbin/modprobe ipmi_si >/dev/null 2>&1
then
/sbin/modprobe ipmi_kcs_drv || RETVAL=1
fi
fi
# If ipmidev still isn't listed in /proc/devices after we load
# modules, this just isn't going to work. Set RETVAL to mark
# this failure.
grep -q ipmidev /proc/devices || RETVAL=1
# Check if the device file exists and create if not.
if [ ! -c /dev/ipmi0 ] && [ $RETVAL -eq 0 ]
then
major=$(awk '/ ipmidev$/{print $1}' /proc/devices)
/bin/mknod -m 0600 /dev/ipmi0 c $major 0 || RETVAL=1
fi
if [ $RETVAL -eq 0 ] && touch /var/lock/subsys/ipmi ; then
echo_success
echo
else
echo_failure
echo
fi
}
stop() {
echo -n $"Shutting down ipmi: "
# Stop doesn't actually do anything because we currently don't
# unload ipmi modules on stop. That might change in the future
# if we decide unloading the ipmi modules is safe.
RETVAL=0
if [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/ipmi ; then
echo_success
echo
else
echo_failure
echo
fi
}
dostatus() {
# Extract cpu temperatures from ipmitool output.
# Abort if we don't have the ipmitool program.
if ! /usr/bin/ipmitool -V >/dev/null
then
echo "/usr/bin/ipmitool not found!" >&2
exit 1
fi
# Abort if ipmi isn't loaded.
if ! grep -q ipmidev /proc/devices
then
echo "ipmi not listed in /proc/devices!" >&2
exit 1
fi
# Check if we are running on a v1.0 IPMI system, and
# change our processor search string appropriately.
if /usr/bin/ipmitool -I open bmc info | \
grep -q "IPMI Version.*1.0"
then
IpmiVersion="1.0"
fi
# Determine # of running processors
NumProcs=$(grep -c processor /proc/cpuinfo)
if [ $NumProcs -eq 0 ]
then
echo "Can't determine number of processors!" >&2
exit 1
fi
# Now build the query string. Concatenate it into
# one string because that's more efficient on 2.4 systems.
Count=1
TempString=""
while [ $Count -le $NumProcs ]
do
if [ x$IpmiVersion = x"1.0" ]
then
TempString="$TempString CPU\ $Count"
else
TempString="$TempString Processor$Count\ Temp"
fi
Count=$((Count + 1))
done
# building TempString like this and eval'ing it is ugly, but
# it's the only way I could make the quoting work. Sorry.
TempString="/usr/bin/ipmitool -I open sensor get $TempString"
eval $TempString | awk -v "c=$Count" '
BEGIN {
n = 1
}
/Sensor Reading/ {
printf "CPU%s Temp: %s\n",n,$4
n++
}
END {
if ( n != c) {
printf "Error: found %s CPUs, but got temps for %s\n",--c,--n >"/dev/stderr"
exit 1
}
exit 0
}'
RETVAL=$((RETVAL + $?))
return $RETVAL
}
restart() {
stop
start
RETVAL=$?
}
condrestart() {
[ -e /var/lock/subsys/ipmi ] && restart || :
}
remove () {
# Actually remove the drivers. Don't do during stop in case
# this causes system to become unstable (a la lm_sensors)
if /sbin/lsmod | awk '{print $1}' | grep -q ipmi_
then
# Try removing both 2.4 and 2.6 modules.
/sbin/rmmod ipmi_si 2>/dev/null
/sbin/rmmod ipmi_kcs_drv 2>/dev/null
/sbin/rmmod ipmi_devintf
/sbin/rmmod ipmi_msghandler
else
echo "No ipmi modules loaded!" >&2
RETVAL=1
return $RETVAL
fi
# Wait a sec to give modules time to unload.
sleep 1
# Check if we failed to remove any modules, and complain if so.
if /sbin/lsmod | awk '{print $1}' | grep -q ipmi_
then
echo "ipmi modules still loaded!" >&2
RETVAL=1
return $RETVAL
fi
}
# See how we were called.
case "$1" in
start)
start
;;
stop)
stop
;;
status)
dostatus
;;
restart|reload)
restart
;;
condrestart)
condrestart
;;
remove)
remove
;;
*)
echo "Usage: ipmi {start|stop|status|restart|condrestart|remove}"
exit 1
esac
exit $RETVAL

View File

@ -58,6 +58,28 @@ rm -rf $RPM_BUILD_DIR/ipmitool-@VERSION@
%doc %{_datadir}/doc/ipmitool/*
%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
- Add a README
- Add support for IPMIv2 and Serial-over-LAN from Newisys

View File

@ -1,3 +1,46 @@
ipmitool (1.8.0) unstable; urgency=low
* Fix IPMIv2.0 issues
* Fix chassis boot parameter support
* Add support for linear sensors
-- Duncan Laurie <duncan@iceblink.org> Wed, Mar 16 2005 17:08:12 -0700
ipmitool (1.7.1) unstable; urgency=low
* Update bmc plugin to work with new Solaris bmc driver (new ioctl
for interface detection and new STREAMS message-based interface).
-- Seth Goldberg <sethmeisterg@hotmail.com> Mon, Mar 7 2005 18:03:00 -0800
ipmitool (1.7.0) unstable; urgency=low
* Propogate errors correctly so exit status will be useful
* 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
* New "bmc" plugin for Solaris 10 x86
* Many bugfixes and contributed patches
-- Duncan Laurie <duncan@iceblink.org> Fri, Jan 7 2005 19:58:22 -0700
ipmitool (1.6.2) unstable; urgency=low
* Support for Supermicro BMC OEM authentication method
-- Duncan Laurie <duncan@iceblink.org> Mon, 16 Nov 2004 08:20:01 -0700
ipmitool (1.6.1) unstable; urgency=low
* Fix minor problem with LAN parameter setting
-- Duncan Laurie <duncan@iceblink.org> Wed, 29 Sep 2004 11:19:17 -0700
ipmitool (1.6.0) unstable; urgency=low
* Add a README

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.
.TP
\fB\-L\fR <\fIprivlvl\fP>
Force sessin privilege level. Can be CALLBACK, USER, OPERATOR, ADMIN. Default is USER.
Force session privilege level. Can be CALLBACK, USER, OPERATOR, ADMIN. Default is ADMIN.
.TP
\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
\fB\-E\fR
The remote server password is specified by the environment variable \fBIPMI_PASSWORD\fR. This option is intended for shell scripts.
@ -63,7 +63,7 @@ This can be used to get command-line help on ipmitool commands. It may also be
.PP
ipmitool -I open help
.br
Commands: bmc, chassis, event, fru, lan, raw, sdr, sel, sensor, sol, isol, userinfo, channel
Commands: bmc, chassis, event, fru, lan, raw, sdr, sel, sensor, sol, userinfo, channel
.LP
.PP
ipmitool -I open chassis help
@ -95,10 +95,10 @@ RAW RSP (5 bytes)
.RS
.TP
\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
.TP
Possible privelige levels are:
Possible privilege levels are:
.br
1 Callback level
.br
@ -310,6 +310,22 @@ This command will query the BMC for information about the SDR.
This command will read the SDR and extract sensor information, then query each sensor and print its name, reading, and status.
.RE
.TP
.I pef
.RS
.TP
.I info
This command will query the BMC and print information about the PEF supported features.
.TP
.I status
This command prints the current PEF status (the last SEL entry processed by the BMC, etc).
.TP
.I policy
This command lists the PEF policy table entries. Each policy entry describes an alert destination. A policy set is a collection of table entries. PEF alert actions reference policy sets.
.TP
.I list
This command lists the PEF table entries. Each PEF entry relates a sensor event to an action. When PEF is active, each platform event causes the BMC to scan this table for entries matching the event, and possible actions to be taken. Actions are performed in priority order (higher criticality first).
.RE
.TP
.I sensor
.RS
.TP
@ -446,15 +462,9 @@ Special escape sequences are provided to control the SOL session:
.RS
.TP
.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
.I isol
.RS
.TP
.I setup
Setup Serial-over-LAN: enable, setup authentication and set baud rate to 19200. This sub-command is specific to Intel motherboards.
.RE
.SH "OPEN INTERFACE"
.LP
The ipmitool \fIopen\fP interface utilizes the MontaVista OpenIPMI kernel device driver. This driver is present in 2.5.57 and later development kernels and in 2.4.21pre1 and later stable kernels. There are also IPMI driver kernel patches for different versions available from the OpenIPMI homepage.
@ -496,10 +506,10 @@ You can tell ipmitool to use the lan interface with the \fB\-I\fR option:
.PP
ipmitool \-I lan \-H <hostname> [\-U username] [\-P password] <expression>
.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"
.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
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

View File

@ -36,7 +36,8 @@ MAINTAINERCLEANFILES = Makefile.in
noinst_HEADERS = log.h bswap.h helper.h ipmi.h ipmi_intf.h \
ipmi_chassis.h ipmi_entity.h ipmi_fru.h ipmi_lanp.h \
ipmi_sdr.h ipmi_sel.h ipmi_sol.h ipmi_bmc.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_strings.h ipmi_constants.h ipmi_isol.h ipmi_user.h
ipmi_strings.h ipmi_constants.h ipmi_user.h ipmi_pef.h \
ipmi_oem.h ipmi_isol.h

View File

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

View File

@ -37,32 +37,29 @@
#ifndef IPMI_HELPER_H
#define IPMI_HELPER_H
#include <sys/types.h>
#include <inttypes.h>
#include <stdio.h>
struct valstr {
unsigned short val;
uint16_t val;
const char * str;
};
const char * val2str(unsigned short val, const struct valstr * vs);
unsigned short str2val(const char * str, const struct valstr * vs);
const char * val2str(uint16_t val, const struct valstr * vs);
uint16_t str2val(const char * str, const struct valstr * vs);
unsigned short buf2short(unsigned char * buf);
uint32_t buf2long(unsigned char * buf);
const char * buf2str(unsigned char * buf, int len);
void printbuf(const unsigned char * buf, int len, const char * desc);
void signal_handler(int sig, void * handler);
unsigned char ipmi_csum(unsigned char * d, int s);
FILE * ipmi_open_file(const char * file, int flags);
uint16_t buf2short(uint8_t * buf);
uint32_t buf2long(uint8_t * buf);
const char * buf2str(uint8_t * buf, int len);
void printbuf(const uint8_t * buf, int len, const char * desc);
uint8_t ipmi_csum(uint8_t * d, int s);
FILE * ipmi_open_file(const char * file, int rw);
#define ipmi_open_file_read(file) ipmi_open_file(file, 0)
#define ipmi_open_file_write(file) ipmi_open_file(file, 1)
#define SIG_IGNORE(s) ((void)signal((s), SIG_IGN))
#define SIG_DEFAULT(s) ((void)signal((s), SIG_DFL))
#define SIG_HANDLE(s,h) ((void)signal_handler((s), (h)))
#define min(a, b) ((a) < (b) ? (a) : (b))
#ifndef __min
# define __min(a, b) ((a) < (b) ? (a) : (b))
#endif
#endif /* IPMI_HELPER_H */

View File

@ -40,6 +40,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <inttypes.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <ipmitool/helper.h>
@ -48,6 +49,7 @@
/* From table 13.16 of the IPMI v2 specification */
#define IPMI_PAYLOAD_TYPE_IPMI 0x00
#define IPMI_PAYLOAD_TYPE_SOL 0x01
#define IPMI_PAYLOAD_TYPE_OEM 0x02
#define IPMI_PAYLOAD_TYPE_RMCP_OPEN_REQUEST 0x10
#define IPMI_PAYLOAD_TYPE_RMCP_OPEN_RESPONSE 0x11
#define IPMI_PAYLOAD_TYPE_RAKP_1 0x12
@ -61,10 +63,11 @@ extern int csv_output;
struct ipmi_rq {
struct {
unsigned char netfn;
unsigned char cmd;
unsigned short data_len;
unsigned char *data;
uint8_t netfn;
uint8_t cmd;
uint8_t target_cmd;
uint16_t data_len;
uint8_t *data;
} msg;
};
@ -74,59 +77,59 @@ struct ipmi_rq {
* is for payload_type to be IPMI_PAYLOAD_TYPE_IPMI.
*/
struct ipmi_v2_payload {
unsigned short payload_length;
unsigned char payload_type;
uint16_t payload_length;
uint8_t payload_type;
union {
struct {
unsigned char rq_seq;
uint8_t rq_seq;
struct ipmi_rq * request;
} ipmi_request;
struct {
unsigned char rs_seq;
uint8_t rs_seq;
struct ipmi_rs * response;
} ipmi_response;
/* Only used internally by the lanplus interface */
struct {
unsigned char * request;
uint8_t * request;
} open_session_request;
/* Only used internally by the lanplus interface */
struct {
unsigned char * message;
uint8_t * message;
} rakp_1_message;
/* Only used internally by the lanplus interface */
struct {
unsigned char * message;
uint8_t * message;
} rakp_2_message;
/* Only used internally by the lanplus interface */
struct {
unsigned char * message;
uint8_t * message;
} rakp_3_message;
/* Only used internally by the lanplus interface */
struct {
unsigned char * message;
uint8_t * message;
} rakp_4_message;
struct {
unsigned char data[IPMI_BUF_SIZE];
unsigned short character_count;
unsigned char packet_sequence_number;
unsigned char acked_packet_number;
unsigned char accepted_character_count;
unsigned char is_nack; /* bool */
unsigned char assert_ring_wor; /* bool */
unsigned char generate_break; /* bool */
unsigned char deassert_cts; /* bool */
unsigned char deassert_dcd_dsr; /* bool */
unsigned char flush_inbound; /* bool */
unsigned char flush_outbound; /* bool */
uint8_t data[IPMI_BUF_SIZE];
uint16_t character_count;
uint8_t packet_sequence_number;
uint8_t acked_packet_number;
uint8_t accepted_character_count;
uint8_t is_nack; /* bool */
uint8_t assert_ring_wor; /* bool */
uint8_t generate_break; /* bool */
uint8_t deassert_cts; /* bool */
uint8_t deassert_dcd_dsr; /* bool */
uint8_t flush_inbound; /* bool */
uint8_t flush_outbound; /* bool */
} sol_packet;
} payload;
@ -137,8 +140,8 @@ struct ipmi_v2_payload {
struct ipmi_rq_entry {
struct ipmi_rq req;
struct ipmi_intf * intf;
unsigned char rq_seq;
unsigned char * msg_data;
uint8_t rq_seq;
uint8_t * msg_data;
int msg_len;
struct ipmi_rq_entry * next;
};
@ -147,8 +150,8 @@ struct ipmi_rq_entry {
struct ipmi_rs {
unsigned char ccode;
unsigned char data[IPMI_BUF_SIZE];
uint8_t ccode;
uint8_t data[IPMI_BUF_SIZE];
/*
* Looks like this is the length of the entire packet, including the RMCP
@ -157,23 +160,23 @@ struct ipmi_rs {
int data_len;
struct {
unsigned char netfn;
unsigned char cmd;
unsigned char seq;
unsigned char lun;
uint8_t netfn;
uint8_t cmd;
uint8_t seq;
uint8_t lun;
} msg;
struct {
unsigned char authtype;
uint8_t authtype;
uint32_t seq;
uint32_t id;
unsigned char bEncrypted; /* IPMI v2 only */
unsigned char bAuthenticated; /* IPMI v2 only */
unsigned char payloadtype; /* IPMI v2 only */
uint8_t bEncrypted; /* IPMI v2 only */
uint8_t bAuthenticated; /* IPMI v2 only */
uint8_t payloadtype; /* IPMI v2 only */
/* This is the total length of the payload or
IPMI message. IPMI v2.0 requires this to
be 2 bytes. Not really used for much. */
unsigned short msglen;
uint16_t msglen;
} session;
@ -182,47 +185,47 @@ struct ipmi_rs {
*/
union {
struct {
unsigned char rq_addr;
unsigned char netfn;
unsigned char rq_lun;
unsigned char rs_addr;
unsigned char rq_seq;
unsigned char rs_lun;
unsigned char cmd;
uint8_t rq_addr;
uint8_t netfn;
uint8_t rq_lun;
uint8_t rs_addr;
uint8_t rq_seq;
uint8_t rs_lun;
uint8_t cmd;
} ipmi_response;
struct {
unsigned char message_tag;
unsigned char rakp_return_code;
unsigned char max_priv_level;
unsigned int console_id;
unsigned int bmc_id;
unsigned char auth_alg;
unsigned char integrity_alg;
unsigned char crypt_alg;
uint8_t message_tag;
uint8_t rakp_return_code;
uint8_t max_priv_level;
uint32_t console_id;
uint32_t bmc_id;
uint8_t auth_alg;
uint8_t integrity_alg;
uint8_t crypt_alg;
} open_session_response;
struct {
unsigned char message_tag;
unsigned char rakp_return_code;
unsigned int console_id;
unsigned char bmc_rand[16]; /* Random number generated by the BMC */
unsigned char bmc_guid[16];
unsigned char key_exchange_auth_code[20];
uint8_t message_tag;
uint8_t rakp_return_code;
uint32_t console_id;
uint8_t bmc_rand[16]; /* Random number generated by the BMC */
uint8_t bmc_guid[16];
uint8_t key_exchange_auth_code[20];
} rakp2_message;
struct {
unsigned char message_tag;
unsigned char rakp_return_code;
unsigned int console_id;
unsigned char integrity_check_value[20];
uint8_t message_tag;
uint8_t rakp_return_code;
uint32_t console_id;
uint8_t integrity_check_value[20];
} rakp4_message;
struct {
unsigned char packet_sequence_number;
unsigned char acked_packet_number;
unsigned char accepted_character_count;
unsigned char is_nack; /* bool */
unsigned char transfer_unavailable; /* bool */
unsigned char sol_inactive; /* bool */
unsigned char transmit_overrun; /* bool */
unsigned char break_detected; /* bool */
uint8_t packet_sequence_number;
uint8_t acked_packet_number;
uint8_t accepted_character_count;
uint8_t is_nack; /* bool */
uint8_t transfer_unavailable; /* bool */
uint8_t sol_inactive; /* bool */
uint8_t transmit_overrun; /* bool */
uint8_t break_detected; /* bool */
} sol_packet;
} payload;
@ -242,6 +245,6 @@ struct ipmi_rs {
#define IPMI_BMC_SLAVE_ADDR 0x20
#define IPMI_REMOTE_SWID 0x81
extern const struct valstr completion_code_vals[25];
extern const struct valstr completion_code_vals[];
#endif /* IPMI_H */

View File

@ -42,14 +42,16 @@
#endif
#include <ipmitool/ipmi.h>
#define IPMI_GET_CHANNEL_AUTH_CAP 0x38
#define IPMI_GET_CHANNEL_ACCESS 0x41
#define IPMI_GET_CHANNEL_INFO 0x42
#define IPMI_SET_USER_ACCESS 0x43
#define IPMI_GET_USER_ACCESS 0x44
#define IPMI_SET_USER_NAME 0x45
#define IPMI_GET_USER_NAME 0x46
#define IPMI_SET_USER_PASSWORD 0x47
#define IPMI_GET_CHANNEL_AUTH_CAP 0x38
#define IPMI_GET_CHANNEL_ACCESS 0x41
#define IPMI_GET_CHANNEL_INFO 0x42
#define IPMI_SET_USER_ACCESS 0x43
#define IPMI_GET_USER_ACCESS 0x44
#define IPMI_SET_USER_NAME 0x45
#define IPMI_GET_USER_NAME 0x46
#define IPMI_SET_USER_PASSWORD 0x47
#define IPMI_GET_CHANNEL_CIPHER_SUITES 0x54
/*
@ -57,44 +59,44 @@
* From table 22-15 of the IPMI v2.0 spec
*/
struct get_channel_auth_cap_rsp {
unsigned char channel_number;
uint8_t channel_number;
#if WORDS_BIGENDIAN
unsigned char v20_data_available : 1; /* IPMI v2.0 data is available */
unsigned char __reserved1 : 1;
unsigned char enabled_auth_types : 6; /* IPMI v1.5 enabled auth types */
uint8_t v20_data_available : 1; /* IPMI v2.0 data is available */
uint8_t __reserved1 : 1;
uint8_t enabled_auth_types : 6; /* IPMI v1.5 enabled auth types */
#else
unsigned char enabled_auth_types : 6; /* IPMI v1.5 enabled auth types */
unsigned char __reserved1 : 1;
unsigned char v20_data_available : 1; /* IPMI v2.0 data is available */
uint8_t enabled_auth_types : 6; /* IPMI v1.5 enabled auth types */
uint8_t __reserved1 : 1;
uint8_t v20_data_available : 1; /* IPMI v2.0 data is available */
#endif
#if WORDS_BIGENDIAN
unsigned char __reserved2 : 2;
unsigned char kg_status : 1; /* two-key login status */
unsigned char per_message_auth : 1; /* per-message authentication status */
unsigned char user_level_auth : 1; /* user-level authentication status */
unsigned char non_null_usernames : 1; /* one or more non-null users exist */
unsigned char null_usernames : 1; /* one or more null usernames non-null pwds */
unsigned char anon_login_enabled : 1; /* a null-named, null-pwd user exists */
uint8_t __reserved2 : 2;
uint8_t kg_status : 1; /* two-key login status */
uint8_t per_message_auth : 1; /* per-message authentication status */
uint8_t user_level_auth : 1; /* user-level authentication status */
uint8_t non_null_usernames : 1; /* one or more non-null users exist */
uint8_t null_usernames : 1; /* one or more null usernames non-null pwds */
uint8_t anon_login_enabled : 1; /* a null-named, null-pwd user exists */
#else
unsigned char anon_login_enabled : 1; /* a null-named, null-pwd user exists */
unsigned char null_usernames : 1; /* one or more null usernames non-null pwds */
unsigned char non_null_usernames : 1; /* one or more non-null users exist */
unsigned char user_level_auth : 1; /* user-level authentication status */
unsigned char per_message_auth : 1; /* per-message authentication status */
unsigned char kg_status : 1; /* two-key login status */
unsigned char __reserved2 : 2;
uint8_t anon_login_enabled : 1; /* a null-named, null-pwd user exists */
uint8_t null_usernames : 1; /* one or more null usernames non-null pwds */
uint8_t non_null_usernames : 1; /* one or more non-null users exist */
uint8_t user_level_auth : 1; /* user-level authentication status */
uint8_t per_message_auth : 1; /* per-message authentication status */
uint8_t kg_status : 1; /* two-key login status */
uint8_t __reserved2 : 2;
#endif
#if WORDS_BIGENDIAN
unsigned char __reserved3 : 6;
unsigned char ipmiv15_support : 1; /* channel supports IPMI v1.5 connections */
unsigned char ipmiv20_support : 1; /* channel supports IPMI v2.0 connections */
uint8_t __reserved3 : 6;
uint8_t ipmiv15_support : 1; /* channel supports IPMI v1.5 connections */
uint8_t ipmiv20_support : 1; /* channel supports IPMI v2.0 connections */
#else
unsigned char ipmiv20_support : 1; /* channel supports IPMI v2.0 connections */
unsigned char ipmiv15_support : 1; /* channel supports IPMI v1.5 connections */
unsigned char __reserved3 : 6;
uint8_t ipmiv20_support : 1; /* channel supports IPMI v2.0 connections */
uint8_t ipmiv15_support : 1; /* channel supports IPMI v1.5 connections */
uint8_t __reserved3 : 6;
#endif
unsigned char oem_id[3]; /* IANA enterprise number for auth type */
unsigned char oem_aux_data; /* Additional OEM specific data for oem auths */
uint8_t oem_id[3]; /* IANA enterprise number for auth type */
uint8_t oem_aux_data; /* Additional OEM specific data for oem auths */
} __attribute__ ((packed));
@ -105,35 +107,35 @@ struct get_channel_auth_cap_rsp {
*/
struct get_channel_info_rsp {
#if WORDS_BIGENDIAN
unsigned char __reserved1 : 4;
unsigned char channel_number : 4; /* channel number */
uint8_t __reserved1 : 4;
uint8_t channel_number : 4; /* channel number */
#else
unsigned char channel_number : 4; /* channel number */
unsigned char __reserved1 : 4;
uint8_t channel_number : 4; /* channel number */
uint8_t __reserved1 : 4;
#endif
#if WORDS_BIGENDIAN
unsigned char __reserved2 : 1;
unsigned char channel_medium : 7; /* Channel medium type per table 6-3 */
uint8_t __reserved2 : 1;
uint8_t channel_medium : 7; /* Channel medium type per table 6-3 */
#else
unsigned char channel_medium : 7; /* Channel medium type per table 6-3 */
unsigned char __reserved2 : 1;
uint8_t channel_medium : 7; /* Channel medium type per table 6-3 */
uint8_t __reserved2 : 1;
#endif
#if WORDS_BIGENDIAN
unsigned char __reserved3 : 3;
unsigned char channel_protocol : 5; /* Channel protocol per table 6-2 */
uint8_t __reserved3 : 3;
uint8_t channel_protocol : 5; /* Channel protocol per table 6-2 */
#else
unsigned char channel_protocol : 5; /* Channel protocol per table 6-2 */
unsigned char __reserved3 : 3;
uint8_t channel_protocol : 5; /* Channel protocol per table 6-2 */
uint8_t __reserved3 : 3;
#endif
#if WORDS_BIGENDIAN
unsigned char session_support : 2; /* Description of session support */
unsigned char active_sessions : 6; /* Count of active sessions */
uint8_t session_support : 2; /* Description of session support */
uint8_t active_sessions : 6; /* Count of active sessions */
#else
unsigned char active_sessions : 6; /* Count of active sessions */
unsigned char session_support : 2; /* Description of session support */
uint8_t active_sessions : 6; /* Count of active sessions */
uint8_t session_support : 2; /* Description of session support */
#endif
unsigned char vendor_id[3]; /* For OEM that specified the protocol */
unsigned char aux_info[2]; /* Not used*/
uint8_t vendor_id[3]; /* For OEM that specified the protocol */
uint8_t aux_info[2]; /* Not used*/
} __attribute__ ((packed));
@ -144,87 +146,88 @@ struct get_channel_info_rsp {
*/
struct get_channel_access_rsp {
#if WORDS_BIGENDIAN
unsigned char __reserved1 : 2;
unsigned char alerting : 1;
unsigned char per_message_auth : 1;
unsigned char user_level_auth : 1;
unsigned char access_mode : 3;
uint8_t __reserved1 : 2;
uint8_t alerting : 1;
uint8_t per_message_auth : 1;
uint8_t user_level_auth : 1;
uint8_t access_mode : 3;
#else
unsigned char access_mode : 3;
unsigned char user_level_auth : 1;
unsigned char per_message_auth : 1;
unsigned char alerting : 1;
unsigned char __reserved1 : 2;
uint8_t access_mode : 3;
uint8_t user_level_auth : 1;
uint8_t per_message_auth : 1;
uint8_t alerting : 1;
uint8_t __reserved1 : 2;
#endif
#if WORDS_BIGENDIAN
unsigned char __reserved2 : 4;
unsigned char channel_priv_limit : 4; /* Channel privilege level limit */
uint8_t __reserved2 : 4;
uint8_t channel_priv_limit : 4; /* Channel privilege level limit */
#else
unsigned char channel_priv_limit : 4; /* Channel privilege level limit */
unsigned char __reserved2 : 4;
uint8_t channel_priv_limit : 4; /* Channel privilege level limit */
uint8_t __reserved2 : 4;
#endif
} __attribute__ ((packed));
struct get_user_access_rsp {
#if WORDS_BIGENDIAN
unsigned char __reserved1 : 2;
unsigned char max_user_ids : 6;
unsigned char __reserved2 : 2;
unsigned char enabled_user_ids : 6;
unsigned char __reserved3 : 2;
unsigned char fixed_user_ids : 6;
unsigned char __reserved4 : 1;
unsigned char callin_callback : 1;
unsigned char link_auth : 1;
unsigned char ipmi_messaging : 1;
unsigned char privilege_limit : 4;
uint8_t __reserved1 : 2;
uint8_t max_user_ids : 6;
uint8_t __reserved2 : 2;
uint8_t enabled_user_ids : 6;
uint8_t __reserved3 : 2;
uint8_t fixed_user_ids : 6;
uint8_t __reserved4 : 1;
uint8_t callin_callback : 1;
uint8_t link_auth : 1;
uint8_t ipmi_messaging : 1;
uint8_t privilege_limit : 4;
#else
unsigned char max_user_ids : 6;
unsigned char __reserved1 : 2;
unsigned char enabled_user_ids : 6;
unsigned char __reserved2 : 2;
unsigned char fixed_user_ids : 6;
unsigned char __reserved3 : 2;
unsigned char privilege_limit : 4;
unsigned char ipmi_messaging : 1;
unsigned char link_auth : 1;
unsigned char callin_callback : 1;
unsigned char __reserved4 : 1;
uint8_t max_user_ids : 6;
uint8_t __reserved1 : 2;
uint8_t enabled_user_ids : 6;
uint8_t __reserved2 : 2;
uint8_t fixed_user_ids : 6;
uint8_t __reserved3 : 2;
uint8_t privilege_limit : 4;
uint8_t ipmi_messaging : 1;
uint8_t link_auth : 1;
uint8_t callin_callback : 1;
uint8_t __reserved4 : 1;
#endif
} __attribute__ ((packed));
struct set_user_access_data {
#if WORDS_BIGENDIAN
unsigned char change_bits : 1;
unsigned char callin_callback : 1;
unsigned char link_auth : 1;
unsigned char ipmi_messaging : 1;
unsigned char channel : 4;
unsigned char __reserved1 : 2;
unsigned char user_id : 6;
unsigned char __reserved2 : 4;
unsigned char privilege_limit : 4;
unsigned char __reserved3 : 4;
unsigned char session_limit : 4;
uint8_t change_bits : 1;
uint8_t callin_callback : 1;
uint8_t link_auth : 1;
uint8_t ipmi_messaging : 1;
uint8_t channel : 4;
uint8_t __reserved1 : 2;
uint8_t user_id : 6;
uint8_t __reserved2 : 4;
uint8_t privilege_limit : 4;
uint8_t __reserved3 : 4;
uint8_t session_limit : 4;
#else
unsigned char channel : 4;
unsigned char ipmi_messaging : 1;
unsigned char link_auth : 1;
unsigned char callin_callback : 1;
unsigned char change_bits : 1;
unsigned char user_id : 6;
unsigned char __reserved1 : 2;
unsigned char privilege_limit : 4;
unsigned char __reserved2 : 4;
unsigned char session_limit : 4;
unsigned char __reserved3 : 4;
uint8_t channel : 4;
uint8_t ipmi_messaging : 1;
uint8_t link_auth : 1;
uint8_t callin_callback : 1;
uint8_t change_bits : 1;
uint8_t user_id : 6;
uint8_t __reserved1 : 2;
uint8_t privilege_limit : 4;
uint8_t __reserved2 : 4;
uint8_t session_limit : 4;
uint8_t __reserved3 : 4;
#endif
} __attribute__ ((packed));
int ipmi_channel_main(struct ipmi_intf *, int, char **);
int ipmi_get_channel_auth_cap(struct ipmi_intf * intf, unsigned char channel, unsigned char priv);
int ipmi_get_channel_info(struct ipmi_intf * intf, unsigned char channel);
uint8_t ipmi_get_channel_medium(struct ipmi_intf * intf, uint8_t channel);
uint8_t ipmi_current_channel_medium(struct ipmi_intf * intf);
int ipmi_channel_main(struct ipmi_intf * intf, int argc, char ** argv);
int ipmi_get_channel_auth_cap(struct ipmi_intf * intf, uint8_t channel, uint8_t priv);
int ipmi_get_channel_info(struct ipmi_intf * intf, uint8_t channel);
#endif /*IPMI_CHANNEL_H*/

View File

@ -70,6 +70,7 @@
#define IPMI_SESSION_AUTHTYPE_OEM 0x5
#define IPMI_SESSION_AUTHTYPE_RMCP_PLUS 0x6
#define IPMI_SESSION_PRIV_UNSPECIFIED 0x0
#define IPMI_SESSION_PRIV_CALLBACK 0x1
#define IPMI_SESSION_PRIV_USER 0x2
#define IPMI_SESSION_PRIV_OPERATOR 0x3
@ -80,4 +81,35 @@
#define IPMI_SET_IN_PROGRESS_IN_PROGRESS 0x01
#define IPMI_SET_IN_PROGRESS_COMMIT_WRITE 0x02
#define IPMI_CHANNEL_MEDIUM_RESERVED 0x0
#define IPMI_CHANNEL_MEDIUM_IPMB 0x1
#define IPMI_CHANNEL_MEDIUM_ICMB_1 0x2
#define IPMI_CHANNEL_MEDIUM_ICMB_09 0x3
#define IPMI_CHANNEL_MEDIUM_LAN 0x4
#define IPMI_CHANNEL_MEDIUM_SERIAL 0x5
#define IPMI_CHANNEL_MEDIUM_LAN_OTHER 0x6
#define IPMI_CHANNEL_MEDIUM_SMBUS_PCI 0x7
#define IPMI_CHANNEL_MEDIUM_SMBUS_1 0x8
#define IPMI_CHANNEL_MEDIUM_SMBUS_2 0x9
#define IPMI_CHANNEL_MEDIUM_USB_1 0xa
#define IPMI_CHANNEL_MEDIUM_USB_2 0xb
#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*/

View File

@ -37,97 +37,15 @@
#ifndef IPMI_ENTITY_H
#define IPMI_ENTITY_H
#include <ipmitool/helper.h>
const struct valstr entity_id_vals[] __attribute__((unused)) = {
{ 0x00, "Unspecified" },
{ 0x01, "Other" },
{ 0x02, "Unknown" },
{ 0x03, "Processor" },
{ 0x04, "Disk or Disk Bay" },
{ 0x05, "Peripheral Bay" },
{ 0x06, "System Management Module" },
{ 0x07, "System Board" },
{ 0x08, "Memory Module" },
{ 0x09, "Processor Module" },
{ 0x0a, "Power Supply" },
{ 0x0b, "Add-in Card" },
{ 0x0c, "Front Panel Board" },
{ 0x0d, "Back Panel Board" },
{ 0x0e, "Power System Board" },
{ 0x0f, "Drive Backplane" },
{ 0x10, "System Internal Expansion Board" },
{ 0x11, "Other System Board" },
{ 0x12, "Processor Board" },
{ 0x13, "Power Unit" },
{ 0x14, "Power Module" },
{ 0x15, "Power Management" },
{ 0x16, "Chassis Back Panel Board" },
{ 0x17, "System Chassis" },
{ 0x18, "Sub-Chassis" },
{ 0x19, "Other Chassis Board" },
{ 0x1a, "Disk Drive Bay" },
{ 0x1b, "Peripheral Bay" },
{ 0x1c, "Device Bay" },
{ 0x1d, "Fan Device" },
{ 0x1e, "Cooling Unit" },
{ 0x1f, "Cable/Interconnect" },
{ 0x20, "Memory Device" },
{ 0x21, "System Management Software" },
{ 0x22, "BIOS" },
{ 0x23, "Operating System" },
{ 0x24, "System Bus" },
{ 0x25, "Group" },
{ 0x26, "Remote Management Device" },
{ 0x27, "External Environment" },
{ 0x28, "Battery" },
{ 0x00, NULL },
};
const struct valstr device_type_vals[] __attribute__((unused)) = {
{ 0x00, "Reserved" },
{ 0x01, "Reserved" },
{ 0x02, "DS1624 temperature sensor" },
{ 0x03, "DS1621 temperature sensor" },
{ 0x04, "LM75 Temperature Sensor" },
{ 0x05, "Heceta ASIC" },
{ 0x06, "Reserved" },
{ 0x07, "Reserved" },
{ 0x08, "EEPROM, 24C01" },
{ 0x09, "EEPROM, 24C02" },
{ 0x0a, "EEPROM, 24C04" },
{ 0x0b, "EEPROM, 24C08" },
{ 0x0c, "EEPROM, 24C16" },
{ 0x0d, "EEPROM, 24C17" },
{ 0x0e, "EEPROM, 24C32" },
{ 0x0f, "EEPROM, 24C64" },
{ 0x1000, "IPMI FRU Inventory" },
{ 0x1001, "DIMM Memory ID" },
{ 0x1002, "IPMI FRU Inventory" },
{ 0x1003, "System Processor Cartridge FRU" },
{ 0x11, "Reserved" },
{ 0x12, "Reserved" },
{ 0x13, "Reserved" },
{ 0x14, "PCF 8570 256 byte RAM" },
{ 0x15, "PCF 8573 clock/calendar" },
{ 0x16, "PCF 8574A I/O Port" },
{ 0x17, "PCF 8583 clock/calendar" },
{ 0x18, "PCF 8593 clock/calendar" },
{ 0x19, "Clock calendar" },
{ 0x1a, "PCF 8591 A/D, D/A Converter" },
{ 0x1b, "I/O Port" },
{ 0x1c, "A/D Converter" },
{ 0x1d, "D/A Converter" },
{ 0x1e, "A/D, D/A Converter" },
{ 0x1f, "LCD Controler/Driver" },
{ 0x20, "Core Logic (Chip set) Device" },
{ 0x21, "LMC6874 Intelligent Battery controller" },
{ 0x22, "Intelligent Batter controller" },
{ 0x23, "Combo Management ASIC" },
{ 0x24, "Maxim 1617 Temperature Sensor" },
{ 0xbf, "Other/Unspecified" },
{ 0x00, NULL },
};
struct entity_id {
uint8_t id; /* physical entity id */
#if WORDS_BIGENDIAN
uint8_t logical : 1; /* physical/logical */
uint8_t instance : 7; /* instance number */
#else
uint8_t instance : 7; /* instance number */
uint8_t logical : 1; /* physical/logical */
#endif
} __attribute__ ((packed));
#endif /* IPMI_ENTITY_H */

View File

@ -39,6 +39,7 @@
#include <inttypes.h>
#include <ipmitool/ipmi.h>
#include <ipmitool/ipmi_sdr.h>
#if HAVE_CONFIG_H
# include <config.h>
@ -64,35 +65,35 @@ enum {
};
struct fru_info {
unsigned short size;
unsigned char access : 1;
uint16_t size;
uint8_t access : 1;
} __attribute__ ((packed));
struct fru_header {
unsigned char version;
uint8_t version;
struct {
unsigned char internal;
unsigned char chassis;
unsigned char board;
unsigned char product;
unsigned char multi;
uint8_t internal;
uint8_t chassis;
uint8_t board;
uint8_t product;
uint8_t multi;
} offset;
unsigned char pad;
unsigned char checksum;
uint8_t pad;
uint8_t checksum;
} __attribute__ ((packed));
struct fru_area_chassis {
unsigned char area_ver;
unsigned char type;
unsigned short area_len;
uint8_t area_ver;
uint8_t type;
uint16_t area_len;
char * part;
char * serial;
};
struct fru_area_board {
unsigned char area_ver;
unsigned char lang;
unsigned short area_len;
uint8_t area_ver;
uint8_t lang;
uint16_t area_len;
uint32_t mfg_date_time;
char * mfg;
char * prod;
@ -102,9 +103,9 @@ struct fru_area_board {
};
struct fru_area_product {
unsigned char area_ver;
unsigned char lang;
unsigned short area_len;
uint8_t area_ver;
uint8_t lang;
uint16_t area_len;
char * mfg;
char * name;
char * part;
@ -121,55 +122,55 @@ struct fru_multirec_header {
#define FRU_RECORD_TYPE_MANAGEMENT_ACCESS 0x03
#define FRU_RECORD_TYPE_BASE_COMPATIBILITY 0x04
#define FRU_RECORD_TYPE_EXTENDED_COMPATIBILITY 0x05
unsigned char type;
unsigned char format;
unsigned char len;
unsigned char record_checksum;
unsigned char header_checksum;
uint8_t type;
uint8_t format;
uint8_t len;
uint8_t record_checksum;
uint8_t header_checksum;
} __attribute__ ((packed));
struct fru_multirec_powersupply {
#if WORDS_BIGENDIAN
unsigned short capacity;
uint16_t capacity;
#else
unsigned short capacity : 12;
unsigned short __reserved1 : 4;
uint16_t capacity : 12;
uint16_t __reserved1 : 4;
#endif
unsigned short peak_va;
unsigned char inrush_current;
unsigned char inrush_interval;
unsigned short lowend_input1;
unsigned short highend_input1;
unsigned short lowend_input2;
unsigned short highend_input2;
unsigned char lowend_freq;
unsigned char highend_freq;
unsigned char dropout_tolerance;
uint16_t peak_va;
uint8_t inrush_current;
uint8_t inrush_interval;
uint16_t lowend_input1;
uint16_t highend_input1;
uint16_t lowend_input2;
uint16_t highend_input2;
uint8_t lowend_freq;
uint8_t highend_freq;
uint8_t dropout_tolerance;
#if WORDS_BIGENDIAN
unsigned char __reserved2 : 3;
unsigned char tach : 1;
unsigned char hotswap : 1;
unsigned char autoswitch : 1;
unsigned char pfc : 1;
unsigned char predictive_fail : 1;
uint8_t __reserved2 : 3;
uint8_t tach : 1;
uint8_t hotswap : 1;
uint8_t autoswitch : 1;
uint8_t pfc : 1;
uint8_t predictive_fail : 1;
#else
unsigned char predictive_fail : 1;
unsigned char pfc : 1;
unsigned char autoswitch : 1;
unsigned char hotswap : 1;
unsigned char tach : 1;
unsigned char __reserved2 : 3;
uint8_t predictive_fail : 1;
uint8_t pfc : 1;
uint8_t autoswitch : 1;
uint8_t hotswap : 1;
uint8_t tach : 1;
uint8_t __reserved2 : 3;
#endif
unsigned short peak_cap_ht;
uint16_t peak_cap_ht;
#if WORDS_BIGENDIAN
unsigned char combined_voltage1 : 4;
unsigned char combined_voltage2 : 4;
uint8_t combined_voltage1 : 4;
uint8_t combined_voltage2 : 4;
#else
unsigned char combined_voltage2 : 4;
unsigned char combined_voltage1 : 4;
uint8_t combined_voltage2 : 4;
uint8_t combined_voltage1 : 4;
#endif
unsigned short combined_capacity;
unsigned char rps_threshold;
uint16_t combined_capacity;
uint8_t rps_threshold;
} __attribute__ ((packed));
static const char * combined_voltage_desc[] __attribute__((unused)) = {
@ -178,36 +179,36 @@ static const char * combined_voltage_desc[] __attribute__((unused)) = {
struct fru_multirec_dcoutput {
#if WORDS_BIGENDIAN
unsigned char standby : 1;
unsigned char __reserved : 3;
unsigned char output_number : 4;
uint8_t standby : 1;
uint8_t __reserved : 3;
uint8_t output_number : 4;
#else
unsigned char output_number : 4;
unsigned char __reserved : 3;
unsigned char standby : 1;
uint8_t output_number : 4;
uint8_t __reserved : 3;
uint8_t standby : 1;
#endif
short nominal_voltage;
short max_neg_dev;
short max_pos_dev;
unsigned short ripple_and_noise;
unsigned short min_current;
unsigned short max_current;
uint16_t ripple_and_noise;
uint16_t min_current;
uint16_t max_current;
} __attribute__ ((packed));
struct fru_multirec_dcload {
#if WORDS_BIGENDIAN
unsigned char __reserved : 4;
unsigned char output_number : 4;
uint8_t __reserved : 4;
uint8_t output_number : 4;
#else
unsigned char output_number : 4;
unsigned char __reserved : 4;
uint8_t output_number : 4;
uint8_t __reserved : 4;
#endif
short nominal_voltage;
short min_voltage;
short max_voltage;
unsigned short ripple_and_noise;
unsigned short min_current;
unsigned short max_current;
uint16_t ripple_and_noise;
uint16_t min_current;
uint16_t max_current;
} __attribute__ ((packed));
static const char * chassis_type_desc[] __attribute__((unused)) = {
@ -221,7 +222,7 @@ static const char * chassis_type_desc[] __attribute__((unused)) = {
"Rack Mount Chassis"
};
void ipmi_print_fru(struct ipmi_intf *, unsigned char);
int ipmi_fru_main(struct ipmi_intf *, int, char **);
int ipmi_fru_main(struct ipmi_intf * intf, int argc, char ** argv);
int ipmi_fru_print(struct ipmi_intf * intf, struct sdr_record_fru_locator * fru);
#endif /* IPMI_FRU_H */

View File

@ -38,6 +38,7 @@
#define IPMI_INTF_H
#include <ipmitool/ipmi.h>
#include <ipmitool/ipmi_oem.h>
#include <ipmitool/ipmi_constants.h>
#include <sys/types.h>
@ -61,18 +62,26 @@ enum LANPLUS_SESSION_STATE {
};
#define IPMI_AUTHCODE_BUFFER_SIZE 16
#define IPMI_AUTHCODE_BUFFER_SIZE 20
#define IPMI_SIK_BUFFER_SIZE 20
#define IPMI_KG_BUFFER_SIZE 21 /* key plus null byte */
struct ipmi_session {
unsigned char hostname[64];
unsigned char username[16];
unsigned char authcode[IPMI_AUTHCODE_BUFFER_SIZE];
unsigned char challenge[16];
unsigned char authtype;
unsigned char authtype_set;
unsigned char privlvl;
uint8_t hostname[64];
uint8_t username[16];
uint8_t authcode[IPMI_AUTHCODE_BUFFER_SIZE + 1];
uint8_t challenge[16];
uint8_t authtype;
uint8_t authtype_set;
#define IPMI_AUTHSTATUS_PER_MSG_DISABLED 0x10
#define IPMI_AUTHSTATUS_PER_USER_DISABLED 0x08
#define IPMI_AUTHSTATUS_NONNULL_USERS_ENABLED 0x04
#define IPMI_AUTHSTATUS_NULL_USERS_ENABLED 0x02
#define IPMI_AUTHSTATUS_ANONYMOUS_USERS_ENABLED 0x01
uint8_t authstatus;
uint8_t authextra;
uint8_t privlvl;
uint8_t cipher_suite_id;
int password;
int port;
int active;
@ -92,10 +101,13 @@ struct ipmi_session {
enum LANPLUS_SESSION_STATE session_state;
/* These are the algorithms agreed upon for the session */
unsigned char auth_alg;
unsigned char integrity_alg;
unsigned char crypt_alg;
unsigned char max_priv_level;
uint8_t requested_auth_alg;
uint8_t requested_integrity_alg;
uint8_t requested_crypt_alg;
uint8_t auth_alg;
uint8_t integrity_alg;
uint8_t crypt_alg;
uint8_t max_priv_level;
uint32_t console_id;
uint32_t bmc_id;
@ -105,18 +117,18 @@ struct ipmi_session {
*/
/* Random number generated byt the console */
unsigned char console_rand[16];
uint8_t console_rand[16];
/* Random number generated by the BMC */
unsigned char bmc_rand[16];
uint8_t bmc_rand[16];
unsigned char bmc_guid[16];
unsigned char requested_role; /* As sent in the RAKP 1 message */
unsigned char rakp2_return_code;
uint8_t bmc_guid[16];
uint8_t requested_role; /* As sent in the RAKP 1 message */
uint8_t rakp2_return_code;
unsigned char sik[IPMI_SIK_BUFFER_SIZE]; /* Session integrity key */
unsigned char kg[IPMI_KG_BUFFER_SIZE]; /* BMC key */
unsigned char k1[20]; /* Used for Integrity checking? */
unsigned char k2[20]; /* First 16 bytes used for AES */
uint8_t sik[IPMI_SIK_BUFFER_SIZE]; /* Session integrity key */
uint8_t kg[IPMI_KG_BUFFER_SIZE]; /* BMC key */
uint8_t k1[20]; /* Used for Integrity checking? */
uint8_t k2[20]; /* First 16 bytes used for AES */
} v2_data;
@ -127,27 +139,26 @@ struct ipmi_session {
uint16_t max_inbound_payload_size;
uint16_t max_outbound_payload_size;
uint16_t port;
unsigned char sequence_number;
uint8_t sequence_number;
/* This data describes the last SOL packet */
unsigned char last_received_sequence_number;
unsigned char last_received_byte_count;
uint8_t last_received_sequence_number;
uint8_t last_received_byte_count;
void (*sol_input_handler)(struct ipmi_rs * rsp);
} sol_data;
};
struct ipmi_intf {
char name[16];
char desc[128];
int fd;
int opened;
int abort;
int thump;
struct ipmi_session * session;
unsigned int my_addr;
unsigned int target_addr;
struct ipmi_oem_handle * oem;
uint32_t my_addr;
uint32_t target_addr;
int (*setup)(struct ipmi_intf * intf);
int (*open)(struct ipmi_intf * intf);
@ -165,8 +176,10 @@ void ipmi_intf_print(void);
void ipmi_intf_session_set_hostname(struct ipmi_intf * intf, char * hostname);
void ipmi_intf_session_set_username(struct ipmi_intf * intf, char * username);
void ipmi_intf_session_set_password(struct ipmi_intf * intf, char * password);
void ipmi_intf_session_set_privlvl(struct ipmi_intf * intf, unsigned char 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_authtype(struct ipmi_intf * intf, unsigned char authtype);
void ipmi_intf_session_set_authtype(struct ipmi_intf * intf, uint8_t authtype);
void ipmi_cleanup(struct ipmi_intf * intf);
#endif /* IPMI_INTF_H */

View File

@ -48,6 +48,11 @@
#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 **);

View File

@ -48,8 +48,11 @@
#define IPMI_CHANNEL_NUMBER_MAX 0xd
extern const struct valstr ipmi_privlvl_vals[];
extern const struct valstr ipmi_authtype_vals[];
#define IPMI_LANP_TIMEOUT 3
#define IPMI_LANP_RETRIES 10
#define IPMI_LANP_WRITE_UNLOCK 0
#define IPMI_LANP_WRITE_LOCK 1
#define IPMI_LANP_WRITE_COMMIT 2
enum {
IPMI_LANP_SET_IN_PROGRESS,
@ -57,21 +60,26 @@ enum {
IPMI_LANP_AUTH_TYPE_ENABLE,
IPMI_LANP_IP_ADDR,
IPMI_LANP_IP_ADDR_SRC,
IPMI_LANP_MAC_ADDR,
IPMI_LANP_MAC_ADDR, /* 5 */
IPMI_LANP_SUBNET_MASK,
IPMI_LANP_IP_HEADER,
IPMI_LANP_PRI_RMCP_PORT,
IPMI_LANP_SEC_RMCP_PORT,
IPMI_LANP_BMC_ARP,
IPMI_LANP_BMC_ARP, /* 10 */
IPMI_LANP_GRAT_ARP,
IPMI_LANP_DEF_GATEWAY_IP,
IPMI_LANP_DEF_GATEWAY_MAC,
IPMI_LANP_BAK_GATEWAY_IP,
IPMI_LANP_BAK_GATEWAY_MAC,
IPMI_LANP_BAK_GATEWAY_MAC, /* 15 */
IPMI_LANP_SNMP_STRING,
IPMI_LANP_NUM_DEST,
IPMI_LANP_DEST_TYPE,
IPMI_LANP_DEST_ADDR,
IPMI_LANP_VLAN_ID, /* 20 */
IPMI_LANP_VLAN_PRIORITY,
IPMI_LANP_RMCP_CIPHER_SUPPORT,
IPMI_LANP_RMCP_CIPHERS,
IPMI_LANP_RMCP_PRIV_LEVELS,
IPMI_LANP_OEM_ALERT_STRING=96,
IPMI_LANP_ALERT_RETRY=97,
IPMI_LANP_UTC_OFFSET=98,
@ -85,35 +93,40 @@ static struct lan_param {
int cmd;
int size;
char desc[24];
unsigned char * data;
uint8_t * data;
int data_len;
} ipmi_lan_params[] __attribute__((unused)) = {
{ IPMI_LANP_SET_IN_PROGRESS, 1, "Set in Progress" },
{ IPMI_LANP_AUTH_TYPE, 1, "Auth Type" },
{ IPMI_LANP_AUTH_TYPE, 1, "Auth Type Support" },
{ IPMI_LANP_AUTH_TYPE_ENABLE, 5, "Auth Type Enable" },
{ IPMI_LANP_IP_ADDR, 4, "IP Address" },
{ IPMI_LANP_IP_ADDR_SRC, 1, "IP Address Source" },
{ IPMI_LANP_MAC_ADDR, 6, "MAC Address" },
{ IPMI_LANP_MAC_ADDR, 6, "MAC Address" }, /* 5 */
{ IPMI_LANP_SUBNET_MASK, 4, "Subnet Mask" },
{ IPMI_LANP_IP_HEADER, 3, "IP Header" },
{ IPMI_LANP_PRI_RMCP_PORT, 2, "Primary RMCP Port" },
{ IPMI_LANP_SEC_RMCP_PORT, 2, "Secondary RMCP Port" },
{ IPMI_LANP_BMC_ARP, 1, "BMC ARP Control" },
{ IPMI_LANP_BMC_ARP, 1, "BMC ARP Control" }, /* 10 */
{ IPMI_LANP_GRAT_ARP, 1, "Gratituous ARP Intrvl" },
{ IPMI_LANP_DEF_GATEWAY_IP, 4, "Default Gateway IP" },
{ IPMI_LANP_DEF_GATEWAY_MAC, 6, "Default Gateway MAC" },
{ IPMI_LANP_BAK_GATEWAY_IP, 4, "Backup Gateway IP" },
{ IPMI_LANP_BAK_GATEWAY_MAC, 6, "Backup Gateway MAC" },
{ IPMI_LANP_BAK_GATEWAY_MAC, 6, "Backup Gateway MAC" }, /* 15 */
{ IPMI_LANP_SNMP_STRING, 18, "SNMP Community String" },
{ IPMI_LANP_NUM_DEST, 1, "Number of Destinations"},
{ IPMI_LANP_DEST_TYPE, 4, "Destination Type" },
{ IPMI_LANP_DEST_ADDR, 13, "Destination Addresses" },
{ IPMI_LANP_OEM_ALERT_STRING, 28, "OEM Alert String" },
{ IPMI_LANP_VLAN_ID, 2, "802.1q VLAN ID" }, /* 20 */
{ IPMI_LANP_VLAN_PRIORITY, 1, "802.1q VLAN Priority" },
{ IPMI_LANP_RMCP_CIPHER_SUPPORT,1, "RMCP+ Cipher Suite Count" },
{ IPMI_LANP_RMCP_CIPHERS, 16, "RMCP+ Cipher Suites" },
{ IPMI_LANP_RMCP_PRIV_LEVELS, 9, "Cipher Suite Priv Max" },
{ IPMI_LANP_OEM_ALERT_STRING, 28, "OEM Alert String" }, /* 25 */
{ IPMI_LANP_ALERT_RETRY, 1, "Alert Retry Algorithm" },
{ IPMI_LANP_UTC_OFFSET, 3, "UTC Offset" },
{ IPMI_LANP_DHCP_SERVER_IP, 4, "DHCP Server IP" },
{ IPMI_LANP_DHCP_SERVER_MAC, 6, "DHDP Server MAC" },
{ IPMI_LANP_DHCP_ENABLE, 1, "DHCP Enable" },
{ IPMI_LANP_DHCP_SERVER_MAC, 6, "DHDP Server MAC" },
{ IPMI_LANP_DHCP_ENABLE, 1, "DHCP Enable" }, /* 30 */
{ IPMI_LANP_CHAN_ACCESS_MODE, 2, "Channel Access Mode" },
{ -1 }
};

View File

@ -34,8 +34,8 @@
* facility.
*/
#ifndef IPMI_BMC_H
#define IPMI_BMC_H
#ifndef IPMI_MC_H
#define IPMI_MC_H
#include <ipmitool/ipmi.h>
@ -45,23 +45,24 @@
#define BMC_GET_SELF_TEST 0x04
#define BMC_SET_GLOBAL_ENABLES 0x2e
#define BMC_GET_GLOBAL_ENABLES 0x2f
#define BMC_GET_GUID 0x37
int ipmi_bmc_main(struct ipmi_intf *, int, char **);
int ipmi_mc_main(struct ipmi_intf *, int, char **);
/*
* Response data from IPM Get Device ID Command (IPMI rev 1.5, section 17.1)
* The following really apply to any IPM device, not just BMCs...
*/
struct ipm_devid_rsp {
unsigned char device_id;
unsigned char device_revision;
unsigned char fw_rev1;
unsigned char fw_rev2;
unsigned char ipmi_version;
unsigned char adtl_device_support;
unsigned char manufacturer_id[3];
unsigned char product_id[2];
unsigned char aux_fw_rev[4];
uint8_t device_id;
uint8_t device_revision;
uint8_t fw_rev1;
uint8_t fw_rev2;
uint8_t ipmi_version;
uint8_t adtl_device_support;
uint8_t manufacturer_id[3];
uint8_t product_id[2];
uint8_t aux_fw_rev[4];
} __attribute__ ((packed));
#define IPM_DEV_DEVICE_ID_SDR_MASK (0x80) /* 1 = provides SDRs */
@ -83,4 +84,4 @@ struct ipm_devid_rsp {
#define IPM_DEV_ADTL_SUPPORT_BITS (8)
#endif /*IPMI_BMC_H*/
#endif /*IPMI_MC_H*/

View File

@ -0,0 +1,51 @@
/*
* 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_OEM_H
#define IPMI_OEM_H
#include <ipmitool/ipmi.h>
/* oem handler, see lib/ipmi_oem.c */
struct ipmi_oem_handle {
const char * name;
const char * desc;
int (*setup)(struct ipmi_intf * intf);
};
void ipmi_oem_print(void);
int ipmi_oem_setup(struct ipmi_intf * intf, char * oemtype);
int ipmi_oem_active(struct ipmi_intf * intf, const char * oemtype);
#endif /*IPMI_OEM_H*/

View File

@ -0,0 +1,788 @@
/*
* Copyright (c) 2004 Dell Computers. 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 Dell Computers, 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.
* DELL COMPUTERS ("DELL") 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
* DELL 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 DELL 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_PEF_H
#define IPMI_PEF_H
#include <ipmitool/ipmi.h>
/* PEF */
struct pef_capabilities { /* "get pef capabilities" response */
uint8_t version;
uint8_t actions; /* mapped by PEF_ACTION_xxx */
uint8_t tblsize;
};
typedef enum {
P_TRUE,
P_SUPP,
P_ACTV,
P_ABLE,
} flg_e;
struct pef_table_entry {
#define PEF_CONFIG_ENABLED 0x80
#define PEF_CONFIG_PRECONFIGURED 0x40
uint8_t config;
#define PEF_ACTION_DIAGNOSTIC_INTERRUPT 0x20
#define PEF_ACTION_OEM 0x10
#define PEF_ACTION_POWER_CYCLE 0x08
#define PEF_ACTION_RESET 0x04
#define PEF_ACTION_POWER_DOWN 0x02
#define PEF_ACTION_ALERT 0x01
uint8_t action;
#define PEF_POLICY_NUMBER_MASK 0x0f
uint8_t policy_number;
#define PEF_SEVERITY_NON_RECOVERABLE 0x20
#define PEF_SEVERITY_CRITICAL 0x10
#define PEF_SEVERITY_WARNING 0x08
#define PEF_SEVERITY_OK 0x04
#define PEF_SEVERITY_INFORMATION 0x02
#define PEF_SEVERITY_MONITOR 0x01
uint8_t severity;
uint8_t generator_ID_addr;
uint8_t generator_ID_lun;
uint8_t sensor_type;
#define PEF_SENSOR_NUMBER_MATCH_ANY 0xff
uint8_t sensor_number;
#define PEF_EVENT_TRIGGER_UNSPECIFIED 0x0
#define PEF_EVENT_TRIGGER_THRESHOLD 0x1
#define PEF_EVENT_TRIGGER_SENSOR_SPECIFIC 0x6f
#define PEF_EVENT_TRIGGER_MATCH_ANY 0xff
uint8_t event_trigger;
uint8_t event_data_1_offset_mask[2];
uint8_t event_data_1_AND_mask;
uint8_t event_data_1_compare_1;
uint8_t event_data_1_compare_2;
uint8_t event_data_2_AND_mask;
uint8_t event_data_2_compare_1;
uint8_t event_data_2_compare_2;
uint8_t event_data_3_AND_mask;
uint8_t event_data_3_compare_1;
uint8_t event_data_3_compare_2;
} __attribute__ ((packed));
struct desc_map { /* maps a description to a value/mask */
const char *desc;
uint32_t mask;
};
struct bit_desc_map { /* description text container */
#define BIT_DESC_MAP_LIST 0x1 /* index-based text array */
#define BIT_DESC_MAP_ANY 0x2 /* bitwise, but only print 1st one */
#define BIT_DESC_MAP_ALL 0x3 /* bitwise, print them all */
uint32_t desc_map_type;
struct desc_map desc_maps[128];
};
static struct bit_desc_map
pef_b2s_actions __attribute__((unused)) = {
BIT_DESC_MAP_ALL,
{ {"Alert", PEF_ACTION_ALERT},
{"Power-off", PEF_ACTION_POWER_DOWN},
{"Reset", PEF_ACTION_RESET},
{"Power-cycle", PEF_ACTION_POWER_CYCLE},
{"OEM-defined", PEF_ACTION_OEM},
{"Diagnostic-interrupt", PEF_ACTION_DIAGNOSTIC_INTERRUPT},
{NULL}
} };
static struct bit_desc_map
pef_b2s_severities __attribute__((unused)) = {
BIT_DESC_MAP_ANY,
{ {"Non-recoverable", PEF_SEVERITY_NON_RECOVERABLE},
{"Critical", PEF_SEVERITY_CRITICAL},
{"Warning", PEF_SEVERITY_WARNING},
{"OK", PEF_SEVERITY_OK},
{"Information", PEF_SEVERITY_INFORMATION},
{"Monitor", PEF_SEVERITY_MONITOR},
{NULL}
} };
static struct bit_desc_map
pef_b2s_sensortypes __attribute__((unused)) = {
BIT_DESC_MAP_LIST,
{ {"Any", 255},
{"Temperature", 1},
{"Voltage", 2},
{"Current", 3},
{"Fan", 4},
{"Chassis Intrusion", 5},
{"Platform security breach", 6},
{"Processor", 7},
{"Power supply", 8},
{"Power Unit", 9},
{"Cooling device", 10},
{"Other (units-based)", 11},
{"Memory", 12},
{"Drive Slot", 13},
{"POST memory resize", 14},
{"POST error", 15},
{"Logging disabled", 16},
{"Watchdog 1", 17},
{"System event", 18},
{"Critical Interrupt", 19},
{"Button", 20},
{"Module/board", 21},
{"uController/coprocessor", 22},
{"Add-in card", 23},
{"Chassis", 24},
{"Chipset", 25},
{"Other (FRU)", 26},
{"Cable/interconnect", 27},
{"Terminator", 28},
{"System boot", 29},
{"Boot error", 30},
{"OS boot", 31},
{"OS critical stop", 32},
{"Slot/connector", 33},
{"ACPI power state", 34},
{"Watchdog 2", 35},
{"Platform alert", 36},
{"Entity presence", 37},
{"Monitor ASIC/IC", 38},
{"LAN", 39},
{"Management subsytem health",40},
{"Battery", 41},
{NULL}
} };
static struct bit_desc_map
pef_b2s_gentype_1 = {
BIT_DESC_MAP_LIST,
{ {"<LNC", 0}, /* '<' : getting worse */
{">LNC", 1}, /* '>' : getting better */
{"<LC", 2},
{">LC", 3},
{"<LNR", 4},
{">LNR", 5},
{">UNC", 6},
{"<UNC", 7},
{">UC", 8},
{"<UC", 9},
{">UNR", 10},
{"<UNR", 11},
{NULL}
} };
static struct bit_desc_map
pef_b2s_gentype_2 = {
BIT_DESC_MAP_LIST,
{ {"transition to idle", 0},
{"transition to active", 1},
{"transition to busy", 2},
{NULL}
} };
static struct bit_desc_map
pef_b2s_gentype_3 = {
BIT_DESC_MAP_LIST,
{ {"state deasserted", 0},
{"state asserted", 1},
{NULL}
} };
static struct bit_desc_map
pef_b2s_gentype_4 = {
BIT_DESC_MAP_LIST,
{ {"predictive failure deasserted", 0},
{"predictive failure asserted", 1},
{NULL}
} };
static struct bit_desc_map
pef_b2s_gentype_5 = {
BIT_DESC_MAP_LIST,
{ {"limit not exceeded", 0},
{"limit exceeded", 1},
{NULL}
} };
static struct bit_desc_map
pef_b2s_gentype_6 = {
BIT_DESC_MAP_LIST,
{ {"performance met", 0},
{"performance lags", 1},
{NULL}
} };
static struct bit_desc_map
pef_b2s_gentype_7 = {
BIT_DESC_MAP_LIST,
{ {"ok", 0},
{"<warn", 1}, /* '<' : getting worse */
{"<fail", 2},
{"<dead", 3},
{">warn", 4}, /* '>' : getting better */
{">fail", 5},
{"dead", 6},
{"monitor", 7},
{"informational", 8},
{NULL}
} };
static struct bit_desc_map
pef_b2s_gentype_8 = {
BIT_DESC_MAP_LIST,
{ {"device removed/absent", 0},
{"device inserted/present", 1},
{NULL}
} };
static struct bit_desc_map
pef_b2s_gentype_9 = {
BIT_DESC_MAP_LIST,
{ {"device disabled", 0},
{"device enabled", 1},
{NULL}
} };
static struct bit_desc_map
pef_b2s_gentype_10 = {
BIT_DESC_MAP_LIST,
{ {"transition to running", 0},
{"transition to in test", 1},
{"transition to power off", 2},
{"transition to online", 3},
{"transition to offline", 4},
{"transition to off duty", 5},
{"transition to degraded", 6},
{"transition to power save", 7},
{"install error", 8},
{NULL}
} };
static struct bit_desc_map
pef_b2s_gentype_11 = {
BIT_DESC_MAP_LIST,
{ {"fully redundant", 0},
{"redundancy lost", 1},
{"redundancy degraded", 2},
{"<non-redundant/sufficient", 3}, /* '<' : getting worse */
{">non-redundant/sufficient", 4}, /* '>' : getting better */
{"non-redundant/insufficient", 5},
{"<redundancy degraded", 6},
{">redundancy degraded", 7},
{NULL}
} };
static struct bit_desc_map
pef_b2s_gentype_12 = {
BIT_DESC_MAP_LIST,
{ {"D0 power state", 0},
{"D1 power state", 1},
{"D2 power state", 2},
{"D3 power state", 3},
{NULL}
} };
static struct bit_desc_map *
pef_b2s_generic_ER[] __attribute__((unused)) = {
&pef_b2s_gentype_1,
&pef_b2s_gentype_2,
&pef_b2s_gentype_3,
&pef_b2s_gentype_4,
&pef_b2s_gentype_5,
&pef_b2s_gentype_6,
&pef_b2s_gentype_7,
&pef_b2s_gentype_8,
&pef_b2s_gentype_9,
&pef_b2s_gentype_10,
&pef_b2s_gentype_11,
&pef_b2s_gentype_12,
};
#define PEF_B2S_GENERIC_ER_ENTRIES \
(sizeof(pef_b2s_generic_ER) / sizeof(pef_b2s_generic_ER[0]))
struct pef_policy_entry {
#define PEF_POLICY_ID_MASK 0xf0
#define PEF_POLICY_ID_SHIFT 4
#define PEF_POLICY_ENABLED 0x08
#define PEF_POLICY_FLAGS_MASK 0x07
#define PEF_POLICY_FLAGS_MATCH_ALWAYS 0
#define PEF_POLICY_FLAGS_PREV_OK_SKIP 1
#define PEF_POLICY_FLAGS_PREV_OK_NEXT_POLICY_SET 2
#define PEF_POLICY_FLAGS_PREV_OK_NEXT_CHANNEL_IN_SET 3
#define PEF_POLICY_FLAGS_PREV_OK_NEXT_DESTINATION_IN_SET 4
uint8_t policy;
#define PEF_POLICY_CHANNEL_MASK 0xf0
#define PEF_POLICY_CHANNEL_SHIFT 4
#define PEF_POLICY_DESTINATION_MASK 0x0f
uint8_t chan_dest;
#define PEF_POLICY_EVENT_SPECIFIC 0x80
uint8_t alert_string_key;
} __attribute__ ((packed));
static struct bit_desc_map
pef_b2s_policies __attribute__((unused)) = {
BIT_DESC_MAP_LIST,
{ {"Match-always", PEF_POLICY_FLAGS_MATCH_ALWAYS},
{"Try-next-entry", PEF_POLICY_FLAGS_PREV_OK_SKIP},
{"Try-next-set", PEF_POLICY_FLAGS_PREV_OK_NEXT_POLICY_SET},
{"Try-next-channel", PEF_POLICY_FLAGS_PREV_OK_NEXT_CHANNEL_IN_SET},
{"Try-next-destination", PEF_POLICY_FLAGS_PREV_OK_NEXT_DESTINATION_IN_SET},
{NULL}
} };
static struct bit_desc_map
pef_b2s_ch_medium __attribute__((unused)) = {
#define PEF_CH_MEDIUM_TYPE_IPMB 1
#define PEF_CH_MEDIUM_TYPE_ICMB_10 2
#define PEF_CH_MEDIUM_TYPE_ICMB_09 3
#define PEF_CH_MEDIUM_TYPE_LAN 4
#define PEF_CH_MEDIUM_TYPE_SERIAL 5
#define PEF_CH_MEDIUM_TYPE_XLAN 6
#define PEF_CH_MEDIUM_TYPE_PCI_SMBUS 7
#define PEF_CH_MEDIUM_TYPE_SMBUS_V1X 8
#define PEF_CH_MEDIUM_TYPE_SMBUS_V2X 9
#define PEF_CH_MEDIUM_TYPE_USB_V1X 10
#define PEF_CH_MEDIUM_TYPE_USB_V2X 11
#define PEF_CH_MEDIUM_TYPE_SYSTEM 12
BIT_DESC_MAP_LIST,
{ {"IPMB (I2C)", PEF_CH_MEDIUM_TYPE_IPMB},
{"ICMB v1.0", PEF_CH_MEDIUM_TYPE_ICMB_10},
{"ICMB v0.9", PEF_CH_MEDIUM_TYPE_ICMB_09},
{"802.3 LAN", PEF_CH_MEDIUM_TYPE_LAN},
{"Serial/Modem (RS-232)", PEF_CH_MEDIUM_TYPE_SERIAL},
{"Other LAN", PEF_CH_MEDIUM_TYPE_XLAN},
{"PCI SMBus", PEF_CH_MEDIUM_TYPE_PCI_SMBUS},
{"SMBus v1.0/1.1", PEF_CH_MEDIUM_TYPE_SMBUS_V1X},
{"SMBus v2.0", PEF_CH_MEDIUM_TYPE_SMBUS_V2X},
{"USB 1.x", PEF_CH_MEDIUM_TYPE_USB_V1X},
{"USB 2.x", PEF_CH_MEDIUM_TYPE_USB_V2X},
{"System I/F (KCS,SMIC,BT)", PEF_CH_MEDIUM_TYPE_SYSTEM},
{NULL}
} };
struct pef_cfgparm_selector {
#define PEF_CFGPARM_ID_REVISION_ONLY_MASK 0x80
#define PEF_CFGPARM_ID_SET_IN_PROGRESS 0
#define PEF_CFGPARM_ID_PEF_CONTROL 1
#define PEF_CFGPARM_ID_PEF_ACTION 2
#define PEF_CFGPARM_ID_PEF_STARTUP_DELAY 3
#define PEF_CFGPARM_ID_PEF_ALERT_STARTUP_DELAY 4
#define PEF_CFGPARM_ID_PEF_FILTER_TABLE_SIZE 5
#define PEF_CFGPARM_ID_PEF_FILTER_TABLE_ENTRY 6
#define PEF_CFGPARM_ID_PEF_FILTER_TABLE_DATA_1 7
#define PEF_CFGPARM_ID_PEF_ALERT_POLICY_TABLE_SIZE 8
#define PEF_CFGPARM_ID_PEF_ALERT_POLICY_TABLE_ENTRY 9
#define PEF_CFGPARM_ID_SYSTEM_GUID 10
#define PEF_CFGPARM_ID_PEF_ALERT_STRING_TABLE_SIZE 11
#define PEF_CFGPARM_ID_PEF_ALERT_STRING_KEY 12
#define PEF_CFGPARM_ID_PEF_ALERT_STRING_TABLE_ENTRY 13
uint8_t id;
uint8_t set;
uint8_t block;
} __attribute__ ((packed));
struct pef_cfgparm_set_in_progress {
#define PEF_SET_IN_PROGRESS_COMMIT_WRITE 0x02
#define PEF_SET_IN_PROGRESS 0x01
uint8_t data1;
} __attribute__ ((packed));
struct pef_cfgparm_control {
#define PEF_CONTROL_ENABLE_ALERT_STARTUP_DELAY 0x08
#define PEF_CONTROL_ENABLE_STARTUP_DELAY 0x04
#define PEF_CONTROL_ENABLE_EVENT_MESSAGES 0x02
#define PEF_CONTROL_ENABLE 0x01
uint8_t data1;
} __attribute__ ((packed));
static struct bit_desc_map
pef_b2s_control __attribute__((unused)) = {
BIT_DESC_MAP_ALL,
{ {"PEF", PEF_CONTROL_ENABLE},
{"PEF event messages", PEF_CONTROL_ENABLE_EVENT_MESSAGES},
{"PEF startup delay", PEF_CONTROL_ENABLE_STARTUP_DELAY},
{"Alert startup delay", PEF_CONTROL_ENABLE_ALERT_STARTUP_DELAY},
{NULL}
} };
struct pef_cfgparm_action {
#define PEF_ACTION_ENABLE_DIAGNOSTIC_INTERRUPT 0x20
#define PEF_ACTION_ENABLE_OEM 0x10
#define PEF_ACTION_ENABLE_POWER_CYCLE 0x08
#define PEF_ACTION_ENABLE_RESET 0x04
#define PEF_ACTION_ENABLE_POWER_DOWN 0x02
#define PEF_ACTION_ENABLE_ALERT 0x01
uint8_t data1;
} __attribute__ ((packed));
struct pef_cfgparm_startup_delay {
uint8_t data1;
} __attribute__ ((packed));
struct pef_cfgparm_alert_startup_delay {
uint8_t data1;
} __attribute__ ((packed));
struct pef_cfgparm_filter_table_size {
#define PEF_FILTER_TABLE_SIZE_MASK 0x7f
uint8_t data1;
} __attribute__ ((packed));
struct pef_cfgparm_filter_table_entry {
#define PEF_FILTER_TABLE_ID_MASK 0x7f
uint8_t data1;
struct pef_table_entry entry;
} __attribute__ ((packed));
struct pef_cfgparm_filter_table_data_1 {
uint8_t data1;
uint8_t data2;
} __attribute__ ((packed));
struct pef_cfgparm_policy_table_size {
#define PEF_POLICY_TABLE_SIZE_MASK 0x7f
uint8_t data1;
} __attribute__ ((packed));
struct pef_cfgparm_policy_table_entry {
#define PEF_POLICY_TABLE_ID_MASK 0x7f
uint8_t data1;
struct pef_policy_entry entry;
} __attribute__ ((packed));
struct pef_cfgparm_system_guid {
#define PEF_SYSTEM_GUID_USED_IN_PET 0x01
uint8_t data1;
uint8_t guid[16];
} __attribute__ ((packed));
struct pef_cfgparm_alert_string_table_size {
#define PEF_ALERT_STRING_TABLE_SIZE_MASK 0x7f
uint8_t data1;
} __attribute__ ((packed));
struct pef_cfgparm_alert_string_keys {
#define PEF_ALERT_STRING_ID_MASK 0x7f
uint8_t data1;
#define PEF_EVENT_FILTER_ID_MASK 0x7f
uint8_t data2;
#define PEF_ALERT_STRING_SET_ID_MASK 0x7f
uint8_t data3;
} __attribute__ ((packed));
struct pef_cfgparm_alert_string_table_entry {
uint8_t id;
uint8_t blockno;
uint8_t block[16];
} __attribute__ ((packed));
/* PEF - LAN */
struct pef_lan_cfgparm_selector {
#define PEF_LAN_CFGPARM_CH_REVISION_ONLY_MASK 0x80
#define PEF_LAN_CFGPARM_CH_MASK 0x0f
#define PEF_LAN_CFGPARM_ID_PET_COMMUNITY 16
#define PEF_LAN_CFGPARM_ID_DEST_COUNT 17
#define PEF_LAN_CFGPARM_ID_DESTTYPE 18
#define PEF_LAN_CFGPARM_ID_DESTADDR 19
uint8_t ch;
uint8_t id;
uint8_t set;
uint8_t block;
} __attribute__ ((packed));
struct pef_lan_cfgparm_dest_size {
#define PEF_LAN_DEST_TABLE_SIZE_MASK 0x0f
uint8_t data1;
} __attribute__ ((packed));
struct pef_lan_cfgparm_dest_type {
#define PEF_LAN_DEST_TYPE_ID_MASK 0x0f
uint8_t dest;
#define PEF_LAN_DEST_TYPE_ACK 0x80
#define PEF_LAN_DEST_TYPE_MASK 0x07
#define PEF_LAN_DEST_TYPE_PET 0
#define PEF_LAN_DEST_TYPE_OEM_1 6
#define PEF_LAN_DEST_TYPE_OEM_2 7
uint8_t dest_type;
uint8_t alert_timeout;
#define PEF_LAN_RETRIES_MASK 0x07
uint8_t retries;
} __attribute__ ((packed));
static struct bit_desc_map
pef_b2s_lan_desttype __attribute__((unused)) = {
BIT_DESC_MAP_LIST,
{ {"Acknowledged", PEF_LAN_DEST_TYPE_ACK},
{"PET", PEF_LAN_DEST_TYPE_PET},
{"OEM 1", PEF_LAN_DEST_TYPE_OEM_1},
{"OEM 2", PEF_LAN_DEST_TYPE_OEM_2},
{NULL}
} };
struct pef_lan_cfgparm_dest_info {
#define PEF_LAN_DEST_MASK 0x0f
uint8_t dest;
#define PEF_LAN_DEST_ADDRTYPE_MASK 0xf0
#define PEF_LAN_DEST_ADDRTYPE_SHIFT 4
#define PEF_LAN_DEST_ADDRTYPE_IPV4_MAC 0x00
uint8_t addr_type;
#define PEF_LAN_DEST_GATEWAY_USE_BACKUP 0x01
uint8_t gateway;
uint8_t ip[4];
uint8_t mac[6];
} __attribute__ ((packed));
/* PEF - Serial/PPP */
struct pef_serial_cfgparm_selector {
#define PEF_SERIAL_CFGPARM_CH_REVISION_ONLY_MASK 0x80
#define PEF_SERIAL_CFGPARM_CH_MASK 0x0f
#define PEF_SERIAL_CFGPARM_ID_DEST_COUNT 16
#define PEF_SERIAL_CFGPARM_ID_DESTINFO 17
#define PEF_SERIAL_CFGPARM_ID_DEST_DIAL_STRING_COUNT 20
#define PEF_SERIAL_CFGPARM_ID_DEST_DIAL_STRING 21
#define PEF_SERIAL_CFGPARM_ID_TAP_ACCT_COUNT 24
#define PEF_SERIAL_CFGPARM_ID_TAP_ACCT_INFO 25
#define PEF_SERIAL_CFGPARM_ID_TAP_ACCT_PAGER_STRING 27
uint8_t ch;
uint8_t id;
uint8_t set;
uint8_t block;
} __attribute__ ((packed));
struct pef_serial_cfgparm_dest_size {
#define PEF_SERIAL_DEST_TABLE_SIZE_MASK 0x0f
uint8_t data1;
} __attribute__ ((packed));
struct pef_serial_cfgparm_dest_info {
#define PEF_SERIAL_DEST_MASK 0x0f
uint8_t dest;
#define PEF_SERIAL_DEST_TYPE_ACK 0x80
#define PEF_SERIAL_DEST_TYPE_MASK 0x0f
#define PEF_SERIAL_DEST_TYPE_DIAL 0
#define PEF_SERIAL_DEST_TYPE_TAP 1
#define PEF_SERIAL_DEST_TYPE_PPP 2
#define PEF_SERIAL_DEST_TYPE_BASIC_CALLBACK 3
#define PEF_SERIAL_DEST_TYPE_PPP_CALLBACK 4
#define PEF_SERIAL_DEST_TYPE_OEM_1 14
#define PEF_SERIAL_DEST_TYPE_OEM_2 15
uint8_t dest_type;
uint8_t alert_timeout;
#define PEF_SERIAL_RETRIES_MASK 0x77
#define PEF_SERIAL_RETRIES_POST_CONNECT_MASK 0x70
#define PEF_SERIAL_RETRIES_PRE_CONNECT_MASK 0x07
uint8_t retries;
#define PEF_SERIAL_DIALPAGE_STRING_ID_MASK 0xf0
#define PEF_SERIAL_DIALPAGE_STRING_ID_SHIFT 4
#define PEF_SERIAL_TAP_PAGE_SERVICE_ID_MASK 0x0f
#define PEF_SERIAL_PPP_ACCT_IPADDR_ID_MASK 0xf0
#define PEF_SERIAL_PPP_ACCT_IPADDR_ID_SHIFT 4
#define PEF_SERIAL_PPP_ACCT_ID_MASK 0x0f
#define PEF_SERIAL_CALLBACK_IPADDR_ID_MASK 0x0f
#define PEF_SERIAL_CALLBACK_IPADDR_ID_SHIFT 4
#define PEF_SERIAL_CALLBACK_ACCT_ID_MASK 0xf0
uint8_t data5;
} __attribute__ ((packed));
static struct bit_desc_map
pef_b2s_serial_desttype __attribute__((unused)) = {
BIT_DESC_MAP_LIST,
{ {"Acknowledged", PEF_SERIAL_DEST_TYPE_ACK},
{"TAP page", PEF_SERIAL_DEST_TYPE_TAP},
{"PPP PET", PEF_SERIAL_DEST_TYPE_PPP},
{"Basic callback", PEF_SERIAL_DEST_TYPE_BASIC_CALLBACK},
{"PPP callback", PEF_SERIAL_DEST_TYPE_PPP_CALLBACK},
{"OEM 1", PEF_SERIAL_DEST_TYPE_OEM_1},
{"OEM 2", PEF_SERIAL_DEST_TYPE_OEM_2},
{NULL}
} };
struct pef_serial_cfgparm_dial_string_count {
#define PEF_SERIAL_DIAL_STRING_COUNT_MASK 0x0f
uint8_t data1;
} __attribute__ ((packed));
struct pef_serial_cfgparm_dial_string {
#define PEF_SERIAL_DIAL_STRING_MASK 0x0f
uint8_t data1;
uint8_t data2;
uint8_t data3;
} __attribute__ ((packed));
struct pef_serial_cfgparm_tap_acct_count {
#define PEF_SERIAL_TAP_ACCT_COUNT_MASK 0x0f
uint8_t data1;
} __attribute__ ((packed));
struct pef_serial_cfgparm_tap_acct_info {
uint8_t data1;
#define PEF_SERIAL_TAP_ACCT_INFO_DIAL_STRING_ID_MASK 0xf0
#define PEF_SERIAL_TAP_ACCT_INFO_DIAL_STRING_ID_SHIFT 4
#define PEF_SERIAL_TAP_ACCT_INFO_SVC_SETTINGS_ID_MASK 0x0f
uint8_t data2;
} __attribute__ ((packed));
struct pef_serial_cfgparm_tap_svc_settings {
uint8_t data1;
#define PEF_SERIAL_TAP_CONFIRMATION_ACK_AFTER_ETX 0x0
#define PEF_SERIAL_TAP_CONFIRMATION_211_ACK_AFTER_ETX 0x01
#define PEF_SERIAL_TAP_CONFIRMATION_21X_ACK_AFTER_ETX 0x02
uint8_t confirmation_flags;
uint8_t service_type[3];
uint8_t escape_mask[4];
uint8_t timeout_parms[3];
uint8_t retry_parms[2];
} __attribute__ ((packed));
static struct bit_desc_map
pef_b2s_tap_svc_confirm __attribute__((unused)) = {
BIT_DESC_MAP_LIST,
{ {"ACK", PEF_SERIAL_TAP_CONFIRMATION_ACK_AFTER_ETX},
{"211+ACK", PEF_SERIAL_TAP_CONFIRMATION_211_ACK_AFTER_ETX},
{"{211|213}+ACK", PEF_SERIAL_TAP_CONFIRMATION_21X_ACK_AFTER_ETX},
{NULL}
} };
#if 0 /* FYI : config parm groupings */
struct pef_config_parms { /* PEF */
struct pef_cfgparm_set_in_progress;
struct pef_cfgparm_control;
struct pef_cfgparm_action;
struct pef_cfgparm_startup_delay; /* in seconds, 1-based */
struct pef_cfgparm_alert_startup_delay; /* in seconds, 1-based */
struct pef_cfgparm_filter_table_size; /* 1-based, READ-ONLY */
struct pef_cfgparm_filter_table_entry;
struct pef_cfgparm_filter_table_data_1;
struct pef_cfgparm_policy_table_size;
struct pef_cfgparm_policy_table_entry;
struct pef_cfgparm_system_guid;
struct pef_cfgparm_alert_string_table_size;
struct pef_cfgparm_alert_string_keys;
struct pef_cfgparm_alert_string_table_entry;
} __attribute__ ((packed));
struct pef_lan_config_parms { /* LAN */
struct pef_lan_cfgparm_set_in_progress;
struct pef_lan_cfgparm_auth_capabilities;
struct pef_lan_cfgparm_auth_type;
struct pef_lan_cfgparm_ip_address;
struct pef_lan_cfgparm_ip_address_source;
struct pef_lan_cfgparm_mac_address;
struct pef_lan_cfgparm_subnet_mask;
struct pef_lan_cfgparm_ipv4_header_parms;
struct pef_lan_cfgparm_primary_rmcp_port;
struct pef_lan_cfgparm_secondary_rmcp_port;
struct pef_lan_cfgparm_bmc_generated_arp_control;
struct pef_lan_cfgparm_gratuitous_arp;
struct pef_lan_cfgparm_default_gateway_ipaddr;
struct pef_lan_cfgparm_default_gateway_macaddr;
struct pef_lan_cfgparm_backup_gateway_ipaddr;
struct pef_lan_cfgparm_backup_gateway_macaddr;
struct pef_lan_cfgparm_pet_community;
struct pef_lan_cfgparm_destination_count;
struct pef_lan_cfgparm_destination_type;
struct pef_lan_cfgparm_destination_ipaddr;
} __attribute__ ((packed));
struct pef_serial_config_parms { /* Serial/PPP */
struct pef_serial_cfgparm_set_in_progress;
struct pef_serial_cfgparm_auth_capabilities;
struct pef_serial_cfgparm_auth_type;
struct pef_serial_cfgparm_connection_mode;
struct pef_serial_cfgparm_idle_timeout;
struct pef_serial_cfgparm_callback_control;
struct pef_serial_cfgparm_session_termination;
struct pef_serial_cfgparm_ipmi_settings;
struct pef_serial_cfgparm_mux_control;
struct pef_serial_cfgparm_modem_ring_time;
struct pef_serial_cfgparm_modem_init_string;
struct pef_serial_cfgparm_modem_escape_sequence;
struct pef_serial_cfgparm_modem_hangup_sequence;
struct pef_serial_cfgparm_modem_dial_command;
struct pef_serial_cfgparm_page_blackout_interval;
struct pef_serial_cfgparm_pet_community;
struct pef_serial_cfgparm_destination_count;
struct pef_serial_cfgparm_destination_info;
struct pef_serial_cfgparm_call_retry_interval;
struct pef_serial_cfgparm_destination_settings;
struct pef_serial_cfgparm_dialstring_count;
struct pef_serial_cfgparm_dialstring_info;
struct pef_serial_cfgparm_ipaddr_count;
struct pef_serial_cfgparm_ipaddr_info;
struct pef_serial_cfgparm_tap_acct_count;
struct pef_serial_cfgparm_tap_acct_info;
struct pef_serial_cfgparm_tap_acct_passwords; /* WRITE only */
struct pef_serial_cfgparm_tap_pager_id_strings;
struct pef_serial_cfgparm_tap_service_settings;
struct pef_serial_cfgparm_terminal_mode_config;
struct pef_serial_cfgparm_ppp_otions;
struct pef_serial_cfgparm_ppp_primary_rmcp_port;
struct pef_serial_cfgparm_ppp_secondary_rmcp_port;
struct pef_serial_cfgparm_ppp_link_auth;
struct pef_serial_cfgparm_ppp_chap_name;
struct pef_serial_cfgparm_ppp_accm;
struct pef_serial_cfgparm_ppp_snoop_accm;
struct pef_serial_cfgparm_ppp_acct_count;
struct pef_serial_cfgparm_ppp_acct_dialstring_selector;
struct pef_serial_cfgparm_ppp_acct_ipaddrs;
struct pef_serial_cfgparm_ppp_acct_user_names;
struct pef_serial_cfgparm_ppp_acct_user_domains;
struct pef_serial_cfgparm_ppp_acct_user_passwords; /* WRITE only */
struct pef_serial_cfgparm_ppp_acct_auth_settings;
struct pef_serial_cfgparm_ppp_acct_connect_hold_times;
struct pef_serial_cfgparm_ppp_udp_proxy_ipheader;
struct pef_serial_cfgparm_ppp_udp_proxy_xmit_bufsize;
struct pef_serial_cfgparm_ppp_udp_proxy_recv_bufsize;
struct pef_serial_cfgparm_ppp_remote_console_ipaddr;
} __attribute__ ((packed));
#endif
#define IPMI_CMD_GET_PEF_CAPABILITIES 0x10
#define IPMI_CMD_GET_PEF_CONFIG_PARMS 0x13
#define IPMI_CMD_GET_LAST_PROCESSED_EVT_ID 0x15
#define IPMI_CMD_GET_SYSTEM_GUID 0x37
#define IPMI_CMD_GET_CHANNEL_INFO 0x42
#define IPMI_CMD_LAN_GET_CONFIG 0x02
#define IPMI_CMD_SERIAL_GET_CONFIG 0x11
const char * ipmi_pef_bit_desc(struct bit_desc_map * map, uint32_t val);
void ipmi_pef_print_flags(struct bit_desc_map * map, flg_e type, uint32_t val);
void ipmi_pef_print_dec(const char * text, uint32_t val);
void ipmi_pef_print_hex(const char * text, uint32_t val);
void ipmi_pef_print_1xd(const char * text, uint32_t val);
void ipmi_pef_print_2xd(const char * text, uint8_t u1, uint8_t u2);
void ipmi_pef_print_str(const char * text, const char * val);
int ipmi_pef_main(struct ipmi_intf * intf, int argc, char ** argv);
#endif /* IPMI_PEF_H */

View File

@ -45,27 +45,28 @@
#include <math.h>
#include <ipmitool/bswap.h>
#include <ipmitool/ipmi.h>
#include <ipmitool/ipmi_entity.h>
int ipmi_sdr_main(struct ipmi_intf *, int, char **);
int utos(unsigned val, unsigned bits);
int32_t utos(uint32_t val, int bits);
#if WORDS_BIGENDIAN
# define __TO_TOL(mtol) (unsigned short)(mtol & 0x3f)
# define __TO_M(mtol) (unsigned short)(utos((((mtol & 0xff00) >> 8) | ((mtol & 0xc0) << 2)), 10))
# define __TO_B(bacc) (unsigned int)(utos((((bacc & 0xff000000) >> 24) | ((bacc & 0xc00000) >> 14)), 10))
# define __TO_ACC(bacc) (unsigned int)(((bacc & 0x3f0000) >> 16) | ((bacc & 0xf000) >> 6))
# define __TO_ACC_EXP(bacc) (unsigned int)((bacc & 0xc00) >> 10)
# define __TO_R_EXP(bacc) (unsigned int)(utos(((bacc & 0xf0) >> 4), 4))
# define __TO_B_EXP(bacc) (unsigned int)(utos((bacc & 0xf), 4))
# define __TO_TOL(mtol) (uint16_t)(mtol & 0x3f)
# define __TO_M(mtol) (int16_t)(utos((((mtol & 0xff00) >> 8) | ((mtol & 0xc0) << 2)), 10))
# define __TO_B(bacc) (int32_t)(utos((((bacc & 0xff000000) >> 24) | ((bacc & 0xc00000) >> 14)), 10))
# define __TO_ACC(bacc) (uint32_t)(((bacc & 0x3f0000) >> 16) | ((bacc & 0xf000) >> 6))
# define __TO_ACC_EXP(bacc) (uint32_t)((bacc & 0xc00) >> 10)
# define __TO_R_EXP(bacc) (int32_t)(utos(((bacc & 0xf0) >> 4), 4))
# define __TO_B_EXP(bacc) (int32_t)(utos((bacc & 0xf), 4))
#else
# define __TO_TOL(mtol) (unsigned short)(BSWAP_16(mtol) & 0x3f)
# define __TO_M(mtol) (unsigned short)(utos((((BSWAP_16(mtol) & 0xff00) >> 8) | ((BSWAP_16(mtol) & 0xc0) << 2)), 10))
# define __TO_B(bacc) (unsigned int)(utos((((BSWAP_32(bacc) & 0xff000000) >> 24) | \
# define __TO_TOL(mtol) (uint16_t)(BSWAP_16(mtol) & 0x3f)
# define __TO_M(mtol) (int16_t)(utos((((BSWAP_16(mtol) & 0xff00) >> 8) | ((BSWAP_16(mtol) & 0xc0) << 2)), 10))
# define __TO_B(bacc) (int32_t)(utos((((BSWAP_32(bacc) & 0xff000000) >> 24) | \
((BSWAP_32(bacc) & 0xc00000) >> 14)), 10))
# define __TO_ACC(bacc) (unsigned int)(((BSWAP_32(bacc) & 0x3f0000) >> 16) | ((BSWAP_32(bacc) & 0xf000) >> 6))
# define __TO_ACC_EXP(bacc) (unsigned int)((BSWAP_32(bacc) & 0xc00) >> 10)
# define __TO_R_EXP(bacc) (unsigned int)(utos(((BSWAP_32(bacc) & 0xf0) >> 4), 4))
# define __TO_B_EXP(bacc) (unsigned int)(utos((BSWAP_32(bacc) & 0xf), 4))
# define __TO_ACC(bacc) (uint32_t)(((BSWAP_32(bacc) & 0x3f0000) >> 16) | ((BSWAP_32(bacc) & 0xf000) >> 6))
# define __TO_ACC_EXP(bacc) (uint32_t)((BSWAP_32(bacc) & 0xc00) >> 10)
# define __TO_R_EXP(bacc) (int32_t)(utos(((BSWAP_32(bacc) & 0xf0) >> 4), 4))
# define __TO_B_EXP(bacc) (int32_t)(utos((BSWAP_32(bacc) & 0xf), 4))
#endif
#define GET_SDR_REPO_INFO 0x20
@ -79,32 +80,32 @@ int utos(unsigned val, unsigned bits);
#define SDR_SENSOR_STAT_HI_NR (1<<5)
struct sdr_repo_info_rs {
unsigned char version; /* SDR version (51h) */
unsigned short count; /* number of records */
unsigned short free; /* free space in SDR */
uint8_t version; /* SDR version (51h) */
uint16_t count; /* number of records */
uint16_t free; /* free space in SDR */
uint32_t add_stamp; /* last add timestamp */
uint32_t erase_stamp; /* last del timestamp */
unsigned char op_support; /* supported operations */
uint8_t op_support; /* supported operations */
} __attribute__ ((packed));
#define GET_SDR_RESERVE_REPO 0x22
struct sdr_reserve_repo_rs {
unsigned short reserve_id; /* reservation ID */
uint16_t reserve_id; /* reservation ID */
} __attribute__ ((packed));
#define GET_SDR 0x23
struct sdr_get_rq {
unsigned short reserve_id; /* reservation ID */
unsigned short id; /* record ID */
unsigned char offset; /* offset into SDR */
uint16_t reserve_id; /* reservation ID */
uint16_t id; /* record ID */
uint8_t offset; /* offset into SDR */
#define GET_SDR_ENTIRE_RECORD 0xff
unsigned char length; /* length to read */
uint8_t length; /* length to read */
} __attribute__ ((packed));
struct sdr_get_rs {
unsigned short next; /* next record id */
unsigned short id; /* record ID */
unsigned char version; /* SDR version (51h) */
uint16_t next; /* next record id */
uint16_t id; /* record ID */
uint8_t version; /* SDR version (51h) */
#define SDR_RECORD_TYPE_FULL_SENSOR 0x01
#define SDR_RECORD_TYPE_COMPACT_SENSOR 0x02
#define SDR_RECORD_TYPE_EVENTONLY_SENSOR 0x03
@ -116,488 +117,418 @@ struct sdr_get_rs {
#define SDR_RECORD_TYPE_MC_CONFIRMATION 0x13
#define SDR_RECORD_TYPE_BMC_MSG_CHANNEL_INFO 0x14
#define SDR_RECORD_TYPE_OEM 0xc0
unsigned char type; /* record type */
unsigned char length; /* remaining record bytes */
uint8_t type; /* record type */
uint8_t length; /* remaining record bytes */
} __attribute__ ((packed));
struct sdr_record_compact_sensor {
struct {
unsigned char owner_id;
uint8_t owner_id;
#if WORDS_BIGENDIAN
unsigned char channel : 4; /* channel number */
unsigned char __reserved : 2;
unsigned char lun : 2; /* sensor owner lun */
uint8_t channel : 4; /* channel number */
uint8_t __reserved : 2;
uint8_t lun : 2; /* sensor owner lun */
#else
unsigned char lun : 2; /* sensor owner lun */
unsigned char __reserved : 2;
unsigned char channel : 4; /* channel number */
uint8_t lun : 2; /* sensor owner lun */
uint8_t __reserved : 2;
uint8_t channel : 4; /* channel number */
#endif
unsigned char sensor_num; /* unique sensor number */
uint8_t sensor_num; /* unique sensor number */
} keys;
struct {
unsigned char id; /* physical entity id */
#if WORDS_BIGENDIAN
unsigned char logical : 1; /* physical/logical */
unsigned char instance : 7; /* instance number */
#else
unsigned char instance : 7; /* instance number */
unsigned char logical : 1; /* physical/logical */
#endif
} entity;
struct entity_id entity;
struct {
struct {
#if WORDS_BIGENDIAN
unsigned char __reserved : 1;
unsigned char scanning : 1;
unsigned char events : 1;
unsigned char thresholds : 1;
unsigned char hysteresis : 1;
unsigned char type : 1;
unsigned char event_gen : 1;
unsigned char sensor_scan : 1;
uint8_t __reserved : 1;
uint8_t scanning : 1;
uint8_t events : 1;
uint8_t thresholds : 1;
uint8_t hysteresis : 1;
uint8_t type : 1;
uint8_t event_gen : 1;
uint8_t sensor_scan : 1;
#else
unsigned char sensor_scan : 1;
unsigned char event_gen : 1;
unsigned char type : 1;
unsigned char hysteresis : 1;
unsigned char thresholds : 1;
unsigned char events : 1;
unsigned char scanning : 1;
unsigned char __reserved : 1;
uint8_t sensor_scan : 1;
uint8_t event_gen : 1;
uint8_t type : 1;
uint8_t hysteresis : 1;
uint8_t thresholds : 1;
uint8_t events : 1;
uint8_t scanning : 1;
uint8_t __reserved : 1;
#endif
} init;
struct {
#if WORDS_BIGENDIAN
unsigned char ignore : 1;
unsigned char rearm : 1;
unsigned char hysteresis : 2;
unsigned char threshold : 2;
unsigned char event_msg : 2;
uint8_t ignore : 1;
uint8_t rearm : 1;
uint8_t hysteresis : 2;
uint8_t threshold : 2;
uint8_t event_msg : 2;
#else
unsigned char event_msg : 2;
unsigned char threshold : 2;
unsigned char hysteresis : 2;
unsigned char rearm : 1;
unsigned char ignore : 1;
uint8_t event_msg : 2;
uint8_t threshold : 2;
uint8_t hysteresis : 2;
uint8_t rearm : 1;
uint8_t ignore : 1;
#endif
} capabilities;
unsigned char type; /* sensor type */
uint8_t type; /* sensor type */
} sensor;
unsigned char event_type; /* event/reading type code */
uint8_t event_type; /* event/reading type code */
union {
struct {
unsigned short assert_event; /* assertion event mask */
unsigned short deassert_event; /* de-assertion event mask */
unsigned short read; /* discrete reaading mask */
uint16_t assert_event; /* assertion event mask */
uint16_t deassert_event; /* de-assertion event mask */
uint16_t read; /* discrete reaading mask */
} discrete;
struct {
unsigned short lower; /* lower threshold reading mask */
unsigned short upper; /* upper threshold reading mask */
unsigned char set; /* settable threshold mask */
unsigned char read; /* readable threshold mask */
uint16_t lower; /* lower threshold reading mask */
uint16_t upper; /* upper threshold reading mask */
uint8_t set; /* settable threshold mask */
uint8_t read; /* readable threshold mask */
} threshold;
} mask;
struct {
#if WORDS_BIGENDIAN
unsigned char analog : 2;
unsigned char rate : 3;
unsigned char modifier : 2;
unsigned char pct : 1;
uint8_t analog : 2;
uint8_t rate : 3;
uint8_t modifier : 2;
uint8_t pct : 1;
#else
unsigned char pct : 1;
unsigned char modifier : 2;
unsigned char rate : 3;
unsigned char analog : 2;
uint8_t pct : 1;
uint8_t modifier : 2;
uint8_t rate : 3;
uint8_t analog : 2;
#endif
struct {
unsigned char base;
unsigned char modifier;
uint8_t base;
uint8_t modifier;
} type;
} unit;
struct {
#if WORDS_BIGENDIAN
unsigned char __reserved : 2;
unsigned char mod_type : 2;
unsigned char count : 4;
uint8_t __reserved : 2;
uint8_t mod_type : 2;
uint8_t count : 4;
#else
unsigned char count : 4;
unsigned char mod_type : 2;
unsigned char __reserved : 2;
uint8_t count : 4;
uint8_t mod_type : 2;
uint8_t __reserved : 2;
#endif
#if WORDS_BIGENDIAN
unsigned char entity_inst : 1;
unsigned char mod_offset : 7;
uint8_t entity_inst : 1;
uint8_t mod_offset : 7;
#else
unsigned char mod_offset : 7;
unsigned char entity_inst : 1;
uint8_t mod_offset : 7;
uint8_t entity_inst : 1;
#endif
} share;
struct {
struct {
unsigned char positive;
unsigned char negative;
uint8_t positive;
uint8_t negative;
} hysteresis;
} threshold;
unsigned char __reserved[3];
unsigned char oem; /* reserved for OEM use */
unsigned char id_code; /* sensor ID string type/length code */
unsigned char id_string[16]; /* sensor ID string bytes, only if id_code != 0 */
uint8_t __reserved[3];
uint8_t oem; /* reserved for OEM use */
uint8_t id_code; /* sensor ID string type/length code */
uint8_t id_string[16]; /* sensor ID string bytes, only if id_code != 0 */
} __attribute__ ((packed));
struct sdr_record_eventonly_sensor {
struct {
unsigned char owner_id;
uint8_t owner_id;
#if WORDS_BIGENDIAN
unsigned char channel : 4; /* channel number */
unsigned char fru_owner : 2; /* fru device owner lun */
unsigned char lun : 2; /* sensor owner lun */
uint8_t channel : 4; /* channel number */
uint8_t fru_owner : 2; /* fru device owner lun */
uint8_t lun : 2; /* sensor owner lun */
#else
unsigned char lun : 2; /* sensor owner lun */
unsigned char fru_owner : 2; /* fru device owner lun */
unsigned char channel : 4; /* channel number */
uint8_t lun : 2; /* sensor owner lun */
uint8_t fru_owner : 2; /* fru device owner lun */
uint8_t channel : 4; /* channel number */
#endif
unsigned char sensor_num; /* unique sensor number */
uint8_t sensor_num; /* unique sensor number */
} keys;
struct {
unsigned char id; /* physical entity id */
#if WORDS_BIGENDIAN
unsigned char logical : 1; /* physical/logical */
unsigned char instance : 7; /* instance number */
#else
unsigned char instance : 7; /* instance number */
unsigned char logical : 1; /* physical/logical */
#endif
} entity;
unsigned char sensor_type; /* sensor type */
unsigned char event_type; /* event/reading type code */
struct entity_id entity;
uint8_t sensor_type; /* sensor type */
uint8_t event_type; /* event/reading type code */
struct {
#if WORDS_BIGENDIAN
unsigned char __reserved : 2;
unsigned char mod_type : 2;
unsigned char count : 4;
uint8_t __reserved : 2;
uint8_t mod_type : 2;
uint8_t count : 4;
#else
unsigned char count : 4;
unsigned char mod_type : 2;
unsigned char __reserved : 2;
uint8_t count : 4;
uint8_t mod_type : 2;
uint8_t __reserved : 2;
#endif
#if WORDS_BIGENDIAN
unsigned char entity_inst : 1;
unsigned char mod_offset : 7;
uint8_t entity_inst : 1;
uint8_t mod_offset : 7;
#else
unsigned char mod_offset : 7;
unsigned char entity_inst : 1;
uint8_t mod_offset : 7;
uint8_t entity_inst : 1;
#endif
} share;
unsigned char __reserved;
unsigned char oem; /* reserved for OEM use */
unsigned char id_code; /* sensor ID string type/length code */
unsigned char id_string[16]; /* sensor ID string bytes, only if id_code != 0 */
uint8_t __reserved;
uint8_t oem; /* reserved for OEM use */
uint8_t id_code; /* sensor ID string type/length code */
uint8_t id_string[16]; /* sensor ID string bytes, only if id_code != 0 */
} __attribute__ ((packed));
struct sdr_record_full_sensor {
struct {
unsigned char owner_id;
uint8_t owner_id;
#if WORDS_BIGENDIAN
unsigned char channel : 4; /* channel number */
unsigned char __reserved : 2;
unsigned char lun : 2; /* sensor owner lun */
uint8_t channel : 4; /* channel number */
uint8_t __reserved : 2;
uint8_t lun : 2; /* sensor owner lun */
#else
unsigned char lun : 2; /* sensor owner lun */
unsigned char __reserved : 2;
unsigned char channel : 4; /* channel number */
uint8_t lun : 2; /* sensor owner lun */
uint8_t __reserved : 2;
uint8_t channel : 4; /* channel number */
#endif
unsigned char sensor_num; /* unique sensor number */
uint8_t sensor_num; /* unique sensor number */
} keys;
struct {
unsigned char id; /* physical entity id */
#if WORDS_BIGENDIAN
unsigned char logical : 1; /* physical/logical */
unsigned char instance : 7; /* instance number */
#else
unsigned char instance : 7; /* instance number */
unsigned char logical : 1; /* physical/logical */
#endif
} entity;
struct entity_id entity;
struct {
struct {
#if WORDS_BIGENDIAN
unsigned char __reserved : 1;
unsigned char scanning : 1;
unsigned char events : 1;
unsigned char thresholds : 1;
unsigned char hysteresis : 1;
unsigned char type : 1;
unsigned char event_gen : 1;
unsigned char sensor_scan : 1;
uint8_t __reserved : 1;
uint8_t scanning : 1;
uint8_t events : 1;
uint8_t thresholds : 1;
uint8_t hysteresis : 1;
uint8_t type : 1;
uint8_t event_gen : 1;
uint8_t sensor_scan : 1;
#else
unsigned char sensor_scan : 1;
unsigned char event_gen : 1;
unsigned char type : 1;
unsigned char hysteresis : 1;
unsigned char thresholds : 1;
unsigned char events : 1;
unsigned char scanning : 1;
unsigned char __reserved : 1;
uint8_t sensor_scan : 1;
uint8_t event_gen : 1;
uint8_t type : 1;
uint8_t hysteresis : 1;
uint8_t thresholds : 1;
uint8_t events : 1;
uint8_t scanning : 1;
uint8_t __reserved : 1;
#endif
} init;
struct {
#if WORDS_BIGENDIAN
unsigned char ignore : 1;
unsigned char rearm : 1;
unsigned char hysteresis : 2;
unsigned char threshold : 2;
unsigned char event_msg : 2;
uint8_t ignore : 1;
uint8_t rearm : 1;
uint8_t hysteresis : 2;
uint8_t threshold : 2;
uint8_t event_msg : 2;
#else
unsigned char event_msg : 2;
unsigned char threshold : 2;
unsigned char hysteresis : 2;
unsigned char rearm : 1;
unsigned char ignore : 1;
uint8_t event_msg : 2;
uint8_t threshold : 2;
uint8_t hysteresis : 2;
uint8_t rearm : 1;
uint8_t ignore : 1;
#endif
} capabilities;
unsigned char type;
uint8_t type;
} sensor;
unsigned char event_type; /* event/reading type code */
uint8_t event_type; /* event/reading type code */
union {
struct {
unsigned short assert_event; /* assertion event mask */
unsigned short deassert_event; /* de-assertion event mask */
unsigned short read; /* discrete reaading mask */
uint16_t assert_event; /* assertion event mask */
uint16_t deassert_event; /* de-assertion event mask */
uint16_t read; /* discrete reaading mask */
} discrete;
struct {
unsigned short lower; /* lower threshold reading mask */
unsigned short upper; /* upper threshold reading mask */
unsigned char set; /* settable threshold mask */
unsigned char read; /* readable threshold mask */
uint16_t lower; /* lower threshold reading mask */
uint16_t upper; /* upper threshold reading mask */
uint8_t set; /* settable threshold mask */
uint8_t read; /* readable threshold mask */
} threshold;
} mask;
struct {
#if WORDS_BIGENDIAN
unsigned char analog : 2;
unsigned char rate : 3;
unsigned char modifier : 2;
unsigned char pct : 1;
uint8_t analog : 2;
uint8_t rate : 3;
uint8_t modifier : 2;
uint8_t pct : 1;
#else
unsigned char pct : 1;
unsigned char modifier : 2;
unsigned char rate : 3;
unsigned char analog : 2;
uint8_t pct : 1;
uint8_t modifier : 2;
uint8_t rate : 3;
uint8_t analog : 2;
#endif
struct {
unsigned char base;
unsigned char modifier;
uint8_t base;
uint8_t modifier;
} type;
} unit;
unsigned char linearization; /* 70h=non linear, 71h-7Fh=non linear, OEM */
unsigned short mtol; /* M, tolerance */
#define SDR_SENSOR_L_LINEAR 0x00
#define SDR_SENSOR_L_LN 0x01
#define SDR_SENSOR_L_LOG10 0x02
#define SDR_SENSOR_L_LOG2 0x03
#define SDR_SENSOR_L_E 0x04
#define SDR_SENSOR_L_EXP10 0x05
#define SDR_SENSOR_L_EXP2 0x06
#define SDR_SENSOR_L_1_X 0x07
#define SDR_SENSOR_L_SQR 0x08
#define SDR_SENSOR_L_CUBE 0x09
#define SDR_SENSOR_L_SQRT 0x0a
#define SDR_SENSOR_L_CUBERT 0x0b
#define SDR_SENSOR_L_NONLINEAR 0x70
uint8_t linearization; /* 70h=non linear, 71h-7Fh=non linear, OEM */
uint16_t mtol; /* M, tolerance */
uint32_t bacc; /* accuracy, B, Bexp, Rexp */
struct {
#if WORDS_BIGENDIAN
unsigned char __reserved : 5;
unsigned char normal_min : 1; /* normal min field specified */
unsigned char normal_max : 1; /* normal max field specified */
unsigned char nominal_read : 1; /* nominal reading field specified */
uint8_t __reserved : 5;
uint8_t normal_min : 1; /* normal min field specified */
uint8_t normal_max : 1; /* normal max field specified */
uint8_t nominal_read : 1; /* nominal reading field specified */
#else
unsigned char nominal_read : 1; /* nominal reading field specified */
unsigned char normal_max : 1; /* normal max field specified */
unsigned char normal_min : 1; /* normal min field specified */
unsigned char __reserved : 5;
uint8_t nominal_read : 1; /* nominal reading field specified */
uint8_t normal_max : 1; /* normal max field specified */
uint8_t normal_min : 1; /* normal min field specified */
uint8_t __reserved : 5;
#endif
} analog_flag;
unsigned char nominal_read; /* nominal reading, raw value */
unsigned char normal_max; /* normal maximum, raw value */
unsigned char normal_min; /* normal minimum, raw value */
unsigned char sensor_max; /* sensor maximum, raw value */
unsigned char sensor_min; /* sensor minimum, raw value */
uint8_t nominal_read; /* nominal reading, raw value */
uint8_t normal_max; /* normal maximum, raw value */
uint8_t normal_min; /* normal minimum, raw value */
uint8_t sensor_max; /* sensor maximum, raw value */
uint8_t sensor_min; /* sensor minimum, raw value */
struct {
struct {
unsigned char non_recover;
unsigned char critical;
unsigned char non_critical;
uint8_t non_recover;
uint8_t critical;
uint8_t non_critical;
} upper;
struct {
unsigned char non_recover;
unsigned char critical;
unsigned char non_critical;
uint8_t non_recover;
uint8_t critical;
uint8_t non_critical;
} lower;
struct {
unsigned char positive;
unsigned char negative;
uint8_t positive;
uint8_t negative;
} hysteresis;
} threshold;
unsigned char __reserved[2];
unsigned char oem; /* reserved for OEM use */
unsigned char id_code; /* sensor ID string type/length code */
unsigned char id_string[16]; /* sensor ID string bytes, only if id_code != 0 */
} __attribute__ ((packed));
struct sdr_record_fru_device_locator {
struct {
#if WORDS_BIGENDIAN
unsigned char __reserved2 : 1;
unsigned char dev_access_addr : 6;
unsigned char __reserved1 : 1;
#else
unsigned char __reserved1 : 1;
unsigned char dev_access_addr : 6;
unsigned char __reserved2 : 1;
#endif
unsigned char fru_device_id;
#if WORDS_BIGENDIAN
unsigned char logical_dev : 1;
unsigned char __reserved3 : 2;
unsigned char access_lun : 2;
unsigned char private_bus : 3;
#else
unsigned char private_bus : 3;
unsigned char access_lun : 2;
unsigned char __reserved3 : 2;
unsigned char logical_dev : 1;
#endif
#if WORDS_BIGENDIAN
unsigned char channel_num : 4;
unsigned char __reserved4 : 4;
#else
unsigned char __reserved4 : 4;
unsigned char channel_num : 4;
#endif
} keys;
unsigned char __reserved;
unsigned char device_type;
unsigned char device_type_modifier;
unsigned char fru_entity_id;
unsigned char fru_entity_instance;
unsigned char oem;
unsigned char id_code;
unsigned char id_string[16];
uint8_t __reserved[2];
uint8_t oem; /* reserved for OEM use */
uint8_t id_code; /* sensor ID string type/length code */
uint8_t id_string[16]; /* sensor ID string bytes, only if id_code != 0 */
} __attribute__ ((packed));
struct sdr_record_mc_locator {
uint8_t dev_slave_addr;
#if WORDS_BIGENDIAN
unsigned char dev_slave_addr : 7;
unsigned char __reserved1 : 1;
uint8_t __reserved2 : 4;
uint8_t channel_num : 4;
#else
unsigned char __reserved1 : 1;
unsigned char dev_slave_addr : 7;
uint8_t channel_num : 4;
uint8_t __reserved2 : 4;
#endif
#if WORDS_BIGENDIAN
unsigned char __reserved2 : 4;
unsigned char channel_num : 4;
uint8_t pwr_state_notif : 3;
uint8_t __reserved3 : 1;
uint8_t global_init : 4;
#else
unsigned char channel_num : 4;
unsigned char __reserved2 : 4;
uint8_t global_init : 4;
uint8_t __reserved3 : 1;
uint8_t pwr_state_notif : 3;
#endif
#if WORDS_BIGENDIAN
unsigned char pwr_state_notif : 3;
unsigned char __reserved3 : 1;
unsigned char global_init : 4;
#else
unsigned char global_init : 4;
unsigned char __reserved3 : 1;
unsigned char pwr_state_notif : 3;
#endif
unsigned char dev_support;
unsigned char __reserved4[3];
struct {
unsigned char id;
unsigned char instance;
} entity;
unsigned char oem;
unsigned char id_code;
unsigned char id_string[16];
uint8_t dev_support;
uint8_t __reserved4[3];
struct entity_id entity;
uint8_t oem;
uint8_t id_code;
uint8_t id_string[16];
} __attribute__ ((packed));
struct sdr_record_fru_locator {
uint8_t dev_slave_addr;
uint8_t device_id;
#if WORDS_BIGENDIAN
unsigned char dev_slave_addr : 7;
unsigned char __reserved1 : 1;
uint8_t logical : 1;
uint8_t __reserved2 : 2;
uint8_t lun : 2;
uint8_t bus : 3;
#else
unsigned char __reserved1 : 1;
unsigned char dev_slave_addr : 7;
#endif
unsigned char device_id;
#if WORDS_BIGENDIAN
unsigned char bus : 3;
unsigned char lun : 2;
unsigned char __reserved2 : 2;
unsigned char logical : 1;
#else
unsigned char logical : 1;
unsigned char __reserved2 : 2;
unsigned char lun : 2;
unsigned char bus : 3;
uint8_t bus : 3;
uint8_t lun : 2;
uint8_t __reserved2 : 2;
uint8_t logical : 1;
#endif
#if WORDS_BIGENDIAN
unsigned char __reserved3 : 4;
unsigned char channel_num : 4;
uint8_t channel_num : 4;
uint8_t __reserved3 : 4;
#else
unsigned char channel_num : 4;
unsigned char __reserved3 : 4;
uint8_t __reserved3 : 4;
uint8_t channel_num : 4;
#endif
unsigned char __reserved4;
unsigned char dev_type;
unsigned char dev_type_modifier;
struct {
unsigned char id;
unsigned char instance;
} entity;
unsigned char oem;
unsigned char id_code;
unsigned char id_string[16];
uint8_t __reserved4;
uint8_t dev_type;
uint8_t dev_type_modifier;
struct entity_id entity;
uint8_t oem;
uint8_t id_code;
uint8_t id_string[16];
} __attribute__ ((packed));
struct sdr_record_oem {
uint8_t * data;
int data_len;
};
/*
* The Get SDR Repository Info response structure
* From table 33-3 of the IPMI v2.0 spec
*/
struct get_sdr_repository_info_rsp {
unsigned char sdr_version;
unsigned char record_count_lsb;
unsigned char record_count_msb;
unsigned char free_space[2];
unsigned char most_recent_addition_timestamp[4];
unsigned char most_recent_erase_timestamp[4];
uint8_t sdr_version;
uint8_t record_count_lsb;
uint8_t record_count_msb;
uint8_t free_space[2];
uint8_t most_recent_addition_timestamp[4];
uint8_t most_recent_erase_timestamp[4];
#if WORDS_BIGENDIAN
unsigned char overflow_flag : 1;
unsigned char modal_update_support : 2;
unsigned char __reserved1 : 1;
unsigned char delete_sdr_supported : 1;
unsigned char partial_add_sdr_supported : 1;
unsigned char reserve_sdr_repository_supported : 1;
unsigned char get_sdr_repository_allo_info_supported : 1;
uint8_t overflow_flag : 1;
uint8_t modal_update_support : 2;
uint8_t __reserved1 : 1;
uint8_t delete_sdr_supported : 1;
uint8_t partial_add_sdr_supported : 1;
uint8_t reserve_sdr_repository_supported : 1;
uint8_t get_sdr_repository_allo_info_supported : 1;
#else
unsigned char get_sdr_repository_allo_info_supported : 1;
unsigned char reserve_sdr_repository_supported : 1;
unsigned char partial_add_sdr_supported : 1;
unsigned char delete_sdr_supported : 1;
unsigned char __reserved1 : 1;
unsigned char modal_update_support : 2;
unsigned char overflow_flag : 1;
uint8_t get_sdr_repository_allo_info_supported : 1;
uint8_t reserve_sdr_repository_supported : 1;
uint8_t partial_add_sdr_supported : 1;
uint8_t delete_sdr_supported : 1;
uint8_t __reserved1 : 1;
uint8_t modal_update_support : 2;
uint8_t overflow_flag : 1;
#endif
} __attribute__ ((packed));
@ -606,14 +537,14 @@ struct get_sdr_repository_info_rsp {
struct ipmi_sdr_iterator
{
unsigned short reservation;
uint16_t reservation;
int total;
int next;
};
struct sdr_record_list {
unsigned short id;
unsigned char type;
uint16_t id;
uint8_t type;
struct sdr_record_list * next;
union {
struct sdr_record_full_sensor * full;
@ -621,6 +552,7 @@ struct sdr_record_list {
struct sdr_record_eventonly_sensor * eventonly;
struct sdr_record_fru_locator * fruloc;
struct sdr_record_mc_locator * mcloc;
struct sdr_record_oem * oem;
} record;
};
@ -669,23 +601,28 @@ static const char * sensor_type_desc[] __attribute__((unused)) = {
struct ipmi_sdr_iterator * ipmi_sdr_start(struct ipmi_intf * intf);
struct sdr_get_rs * ipmi_sdr_get_next_header(struct ipmi_intf * intf, struct ipmi_sdr_iterator * i);
unsigned char * ipmi_sdr_get_record(struct ipmi_intf * intf, struct sdr_get_rs * header, struct ipmi_sdr_iterator * i);
uint8_t * ipmi_sdr_get_record(struct ipmi_intf * intf, struct sdr_get_rs * header, struct ipmi_sdr_iterator * i);
void ipmi_sdr_end(struct ipmi_intf * intf, struct ipmi_sdr_iterator * i);
void ipmi_sdr_print_sdr(struct ipmi_intf * intf, unsigned char type);
const char * ipmi_sdr_get_status(unsigned char stat);
float sdr_convert_sensor_reading(struct sdr_record_full_sensor * sensor, unsigned char val);
unsigned char sdr_convert_sensor_value_to_raw(struct sdr_record_full_sensor * sensor, float val);
struct ipmi_rs * ipmi_sdr_get_sensor_reading(struct ipmi_intf * intf, unsigned char sensor);
const char * ipmi_sdr_get_sensor_type_desc(const unsigned char type);
int ipmi_sdr_print_sdr(struct ipmi_intf * intf, uint8_t type);
int ipmi_sdr_print_rawentry(struct ipmi_intf * intf, uint8_t type, uint8_t * raw, int len);
int ipmi_sdr_print_listentry(struct ipmi_intf * intf, struct sdr_record_list * entry);
const char * ipmi_sdr_get_status(uint8_t stat);
double sdr_convert_sensor_reading(struct sdr_record_full_sensor * sensor, uint8_t val);
uint8_t sdr_convert_sensor_value_to_raw(struct sdr_record_full_sensor * sensor, double val);
struct ipmi_rs * ipmi_sdr_get_sensor_reading(struct ipmi_intf * intf, uint8_t sensor);
const char * ipmi_sdr_get_sensor_type_desc(const uint8_t type);
void ipmi_sdr_print_sensor_full(struct ipmi_intf * intf, struct sdr_record_full_sensor * sensor);
void ipmi_sdr_print_sensor_compact(struct ipmi_intf * intf, struct sdr_record_compact_sensor * sensor);
void ipmi_sdr_print_sensor_eventonly(struct ipmi_intf * intf, struct sdr_record_eventonly_sensor * sensor);
void ipmi_sdr_print_fru_locator(struct ipmi_intf * intf, struct sdr_record_fru_locator * fru);
void ipmi_sdr_print_mc_locator(struct ipmi_intf * intf, struct sdr_record_mc_locator * mc);
int ipmi_sdr_print_sensor_full(struct ipmi_intf * intf, struct sdr_record_full_sensor * sensor);
int ipmi_sdr_print_sensor_compact(struct ipmi_intf * intf, struct sdr_record_compact_sensor * sensor);
int ipmi_sdr_print_sensor_eventonly(struct ipmi_intf * intf, struct sdr_record_eventonly_sensor * sensor);
int ipmi_sdr_print_sensor_fru_locator(struct ipmi_intf * intf, struct sdr_record_fru_locator * fru);
int ipmi_sdr_print_sensor_mc_locator(struct ipmi_intf * intf, struct sdr_record_mc_locator * mc);
struct sdr_record_list * ipmi_sdr_find_sdr_byentity(struct ipmi_intf * intf, struct entity_id * entity);
struct sdr_record_list * ipmi_sdr_find_sdr_bynumtype(struct ipmi_intf * intf, uint8_t num, uint8_t type);
struct sdr_record_list * ipmi_sdr_find_sdr_byid(struct ipmi_intf * intf, char * id);
void ipmi_sdr_list_empty(struct ipmi_intf * intf);
int ipmi_sdr_print_info(struct ipmi_intf * intf);
void ipmi_sdr_print_discrete_state(uint8_t sensor_type, uint8_t event_type, uint8_t state);
#endif /* IPMI_SDR_H */

View File

@ -61,50 +61,50 @@ enum {
};
struct sel_get_rq {
unsigned short reserve_id;
unsigned short record_id;
unsigned char offset;
unsigned char length;
uint16_t reserve_id;
uint16_t record_id;
uint8_t offset;
uint8_t length;
} __attribute__ ((packed));
struct sel_event_record {
unsigned short record_id;
unsigned char record_type;
uint16_t record_id;
uint8_t record_type;
uint32_t timestamp;
unsigned short gen_id;
unsigned char evm_rev;
unsigned char sensor_type;
unsigned char sensor_num;
unsigned char event_type : 7;
unsigned char event_dir : 1;
uint16_t gen_id;
uint8_t evm_rev;
uint8_t sensor_type;
uint8_t sensor_num;
uint8_t event_type : 7;
uint8_t event_dir : 1;
#define DATA_BYTE2_SPECIFIED_MASK 0xc0 /* event_data[0] bit mask */
#define DATA_BYTE3_SPECIFIED_MASK 0x30 /* event_data[0] bit mask */
#define EVENT_OFFSET_MASK 0x0f /* event_data[0] bit mask */
unsigned char event_data[3];
uint8_t event_data[3];
} __attribute__ ((packed));
struct sel_oem_record_ts {
unsigned short next_id;
unsigned short record_id;
unsigned char record_type;
uint16_t next_id;
uint16_t record_id;
uint8_t record_type;
uint32_t timestamp;
unsigned char mfg_id[3];
unsigned char oem_defined[6];
uint8_t mfg_id[3];
uint8_t oem_defined[6];
} __attribute__ ((packed));
struct sel_oem_record_nots {
unsigned short next_id;
unsigned short record_id;
unsigned char record_type;
unsigned char oem_defined[13];
uint16_t next_id;
uint16_t record_id;
uint8_t record_type;
uint8_t oem_defined[13];
} __attribute__ ((packed));
struct ipmi_event_sensor_types {
unsigned char code;
unsigned char offset;
uint8_t code;
uint8_t offset;
#define ALL_OFFSETS_SPECIFIED 0xff
unsigned char data;
unsigned char class;
uint8_t data;
uint8_t class;
const char * type;
const char * desc;
};
@ -138,7 +138,7 @@ static struct ipmi_event_sensor_types generic_event_types[] __attribute__((unuse
{ 0x06, 0x01, 0xff, IPMI_EVENT_CLASS_DIGITAL, "Digital State", "Performance Lags" },
/* Severity Event States */
{ 0x07, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Severity State", "Transition to OK" },
{ 0x07, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Severity State", "Transition to Non-critial from OK" },
{ 0x07, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Severity State", "Transition to Non-critical from OK" },
{ 0x07, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Severity State", "Transition to Critical from less severe" },
{ 0x07, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Severity State", "Transition to Non-recoverable from less severe" },
{ 0x07, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Severity State", "Transition to Non-critical from more severe" },
@ -194,7 +194,7 @@ static struct ipmi_event_sensor_types sensor_specific_types[] __attribute__((unu
{ 0x05, 0x06, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Physical Security", "FAN area intrusion" },
{ 0x06, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Platform Security", "Front Panel Lockout violation attempted" },
{ 0x06, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Platform Security", "Pre-boot password viiolation - user password" },
{ 0x06, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Platform Security", "Pre-boot password violation - user password" },
{ 0x06, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Platform Security", "Pre-boot password violation - setup password" },
{ 0x06, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Platform Security", "Pre-boot password violation - network boot password" },
{ 0x06, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Platform Security", "Other pre-boot password violation" },
@ -267,7 +267,7 @@ static struct ipmi_event_sensor_types sensor_specific_types[] __attribute__((unu
{ 0x12, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Event", "System Reconfigured" },
{ 0x12, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Event", "OEM System boot event" },
{ 0x12, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Event", "Undetermined system hardware failure" },
{ 0x12, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Event", "Entry added to auxillary log" },
{ 0x12, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Event", "Entry added to auxiliary log" },
{ 0x12, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Event", "PEF Action" },
{ 0x12, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Event", "Timestamp Clock Sync." },
@ -320,11 +320,11 @@ static struct ipmi_event_sensor_types sensor_specific_types[] __attribute__((unu
{ 0x21, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Fault Status asserted" },
{ 0x21, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Identify Status asserted" },
{ 0x21, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Slot/Connector Device installed/attached" },
{ 0x21, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Slot/Connector ready for device installation" },
{ 0x21, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Slot/Connector ready for device removal" },
{ 0x21, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Device installed/attached" },
{ 0x21, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Ready for device installation" },
{ 0x21, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Ready for device removal" },
{ 0x21, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Slot Power is off" },
{ 0x21, 0x06, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Slot/Connector device removal request" },
{ 0x21, 0x06, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Device removal request" },
{ 0x21, 0x07, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Interlock asserted" },
{ 0x21, 0x08, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Slot is disabled" },
@ -383,6 +383,6 @@ int ipmi_sel_main(struct ipmi_intf *, int, char **);
void ipmi_sel_print_std_entry(struct sel_event_record * evt);
void ipmi_sel_print_std_entry_verbose(struct sel_event_record * evt);
void ipmi_get_event_desc(struct sel_event_record * rec, char ** desc);
const char * ipmi_sel_get_sensor_type(unsigned char code);
const char * ipmi_sel_get_sensor_type(uint8_t code);
#endif /* IPMI_SEL_H */

View File

@ -40,6 +40,7 @@
#include <math.h>
#include <ipmitool/bswap.h>
#include <ipmitool/ipmi.h>
#include <ipmitool/ipmi_sdr.h>
/* ipmi sensor commands */
#define GET_SENSOR_READING 0x2d
@ -76,19 +77,19 @@
#define STATE_14_ASSERTED 0x40
struct sensor_set_thresh_rq {
unsigned char sensor_num; /* sensor # */
unsigned char set_mask; /* threshold setting mask */
unsigned char lower_non_crit; /* new lower non critical threshold*/
unsigned char lower_crit; /* new lower critical threshold*/
unsigned char lower_non_recov; /* new lower non recoverable threshold*/
unsigned char upper_non_crit; /* new upper non critical threshold*/
unsigned char upper_crit; /* new upper critical threshold*/
unsigned char upper_non_recov; /* new upper non recoverable threshold*/
uint8_t sensor_num; /* sensor # */
uint8_t set_mask; /* threshold setting mask */
uint8_t lower_non_crit; /* new lower non critical threshold*/
uint8_t lower_crit; /* new lower critical threshold*/
uint8_t lower_non_recov; /* new lower non recoverable threshold*/
uint8_t upper_non_crit; /* new upper non critical threshold*/
uint8_t upper_crit; /* new upper critical threshold*/
uint8_t upper_non_recov; /* new upper non recoverable threshold*/
} __attribute__ ((packed));
int ipmi_sensor_main(struct ipmi_intf *, int, char **);
void ipmi_sensor_print_full(struct ipmi_intf *, struct sdr_record_full_sensor *);
void ipmi_sensor_print_compact(struct ipmi_intf *, struct sdr_record_compact_sensor *);
int ipmi_sensor_print_full(struct ipmi_intf *, struct sdr_record_full_sensor *);
int ipmi_sensor_print_compact(struct ipmi_intf *, struct sdr_record_compact_sensor *);
#endif /* IPMI_SENSOR_H */

View File

@ -49,46 +49,46 @@
*/
struct get_session_info_rsp
{
unsigned char session_handle;
uint8_t session_handle;
#if WORDS_BIGENDIAN
unsigned char __reserved1 : 2;
unsigned char session_slot_count : 6; /* 1-based */
uint8_t __reserved1 : 2;
uint8_t session_slot_count : 6; /* 1-based */
#else
unsigned char session_slot_count : 6; /* 1-based */
unsigned char __reserved1 : 2;
uint8_t session_slot_count : 6; /* 1-based */
uint8_t __reserved1 : 2;
#endif
#if WORDS_BIGENDIAN
unsigned char __reserved2 : 2;
unsigned char active_session_count : 6; /* 1-based */
uint8_t __reserved2 : 2;
uint8_t active_session_count : 6; /* 1-based */
#else
unsigned char active_session_count : 6; /* 1-based */
unsigned char __reserved2 : 2;
uint8_t active_session_count : 6; /* 1-based */
uint8_t __reserved2 : 2;
#endif
#if WORDS_BIGENDIAN
unsigned char __reserved3 : 2;
unsigned char user_id : 6;
uint8_t __reserved3 : 2;
uint8_t user_id : 6;
#else
unsigned char user_id : 6;
unsigned char __reserved3 : 2;
uint8_t user_id : 6;
uint8_t __reserved3 : 2;
#endif
#if WORDS_BIGENDIAN
unsigned char __reserved4 : 4;
unsigned char privilege_level : 4;
uint8_t __reserved4 : 4;
uint8_t privilege_level : 4;
#else
unsigned char privilege_level : 4;
unsigned char __reserved4 : 4;
uint8_t privilege_level : 4;
uint8_t __reserved4 : 4;
#endif
#if WORDS_BIGENDIAN
unsigned char auxiliary_data : 4;
unsigned char channel_number : 4;
uint8_t auxiliary_data : 4;
uint8_t channel_number : 4;
#else
unsigned char channel_number : 4;
unsigned char auxiliary_data : 4;
uint8_t channel_number : 4;
uint8_t auxiliary_data : 4;
#endif
union
@ -96,25 +96,25 @@ struct get_session_info_rsp
/* Only exists if channel type is 802.3 LAN */
struct
{
unsigned char console_ip[4]; /* MSBF */
unsigned char console_mac[6]; /* MSBF */
uint8_t console_ip[4]; /* MSBF */
uint8_t console_mac[6]; /* MSBF */
uint16_t console_port; /* LSBF */
} lan_data;
/* Only exists if channel type is async. serial modem */
struct
{
unsigned char session_channel_activity_type;
uint8_t session_channel_activity_type;
#if WORDS_BIGENDIAN
unsigned char __reserved5 : 4;
unsigned char destination_selector : 4;
uint8_t __reserved5 : 4;
uint8_t destination_selector : 4;
#else
unsigned char destination_selector : 4;
unsigned char __reserved5 : 4;
uint8_t destination_selector : 4;
uint8_t __reserved5 : 4;
#endif
unsigned char console_ip[4]; /* MSBF */
uint8_t console_ip[4]; /* MSBF */
/* Only exists if session is PPP */
uint16_t console_port; /* LSBF */

View File

@ -48,19 +48,19 @@
struct sol_config_parameters {
unsigned char set_in_progress;
unsigned char enabled;
unsigned char force_encryption;
unsigned char force_authentication;
unsigned char privilege_level;
unsigned char character_accumulate_level;
unsigned char character_send_threshold;
unsigned char retry_count;
unsigned char retry_interval;
unsigned char non_volatile_bit_rate;
unsigned char volatile_bit_rate;
unsigned char payload_channel;
unsigned short payload_port;
uint8_t set_in_progress;
uint8_t enabled;
uint8_t force_encryption;
uint8_t force_authentication;
uint8_t privilege_level;
uint8_t character_accumulate_level;
uint8_t character_send_threshold;
uint8_t retry_count;
uint8_t retry_interval;
uint8_t non_volatile_bit_rate;
uint8_t volatile_bit_rate;
uint8_t payload_channel;
uint16_t payload_port;
};
@ -69,17 +69,17 @@ struct sol_config_parameters {
* From table 24-2 of the IPMI v2.0 spec
*/
struct activate_payload_rsp {
unsigned char auxiliary_data[4];
unsigned char inbound_payload_size[2]; /* LS byte first */
unsigned char outbound_payload_size[2]; /* LS byte first */
unsigned char payload_udp_port[2]; /* LS byte first */
unsigned char payload_vlan_number[2]; /* LS byte first */
uint8_t auxiliary_data[4];
uint8_t inbound_payload_size[2]; /* LS byte first */
uint8_t outbound_payload_size[2]; /* LS byte first */
uint8_t payload_udp_port[2]; /* LS byte first */
uint8_t payload_vlan_number[2]; /* LS byte first */
} __attribute__ ((packed));
int ipmi_sol_main(struct ipmi_intf *, int, char **);
int ipmi_get_sol_info(struct ipmi_intf * intf,
unsigned char channel,
uint8_t channel,
struct sol_config_parameters * params);

View File

@ -39,12 +39,21 @@
#include <ipmitool/helper.h>
extern const struct valstr completion_code_vals[];
extern const struct valstr entity_id_vals[];
extern const struct valstr entity_device_type_vals[];
extern const struct valstr ipmi_channel_activity_type_vals[];
extern const struct valstr ipmi_privlvl_vals[];
extern const struct valstr impi_bit_rate_vals[];
extern const struct valstr ipmi_set_in_progress_vals[];
extern const struct valstr ipmi_authtype_session_vals[];
extern const struct valstr ipmi_authtype_vals[];
extern const struct valstr ipmi_channel_protocol_vals[];
extern const struct valstr ipmi_channel_medium_vals[];
extern const struct valstr ipmi_auth_algorithms[];
extern const struct valstr ipmi_integrity_algorithms[];
extern const struct valstr ipmi_encryption_algorithms[];
#endif /*IPMI_STRINGS_H*/

View File

@ -48,41 +48,41 @@
*/
struct user_access_rsp {
#if WORDS_BIGENDIAN
unsigned char __reserved1 : 2;
unsigned char maximum_ids : 6;
uint8_t __reserved1 : 2;
uint8_t maximum_ids : 6;
#else
unsigned char maximum_ids : 6;
unsigned char __reserved1 : 2;
uint8_t maximum_ids : 6;
uint8_t __reserved1 : 2;
#endif
#if WORDS_BIGENDIAN
unsigned char __reserved2 : 2;
unsigned char enabled_user_count : 6;
uint8_t __reserved2 : 2;
uint8_t enabled_user_count : 6;
#else
unsigned char enabled_user_count : 6;
unsigned char __reserved2 : 2;
uint8_t enabled_user_count : 6;
uint8_t __reserved2 : 2;
#endif
#if WORDS_BIGENDIAN
unsigned char __reserved3 : 2;
unsigned char fixed_name_count : 6;
uint8_t __reserved3 : 2;
uint8_t fixed_name_count : 6;
#else
unsigned char fixed_name_count : 6;
unsigned char __reserved3 : 2;
uint8_t fixed_name_count : 6;
uint8_t __reserved3 : 2;
#endif
#if WORDS_BIGENDIAN
unsigned char __reserved4 : 1;
unsigned char no_callin_access : 1;
unsigned char link_auth_access : 1;
unsigned char ipmi_messaging_access : 1;
unsigned char channel_privilege_limit : 4;
uint8_t __reserved4 : 1;
uint8_t no_callin_access : 1;
uint8_t link_auth_access : 1;
uint8_t ipmi_messaging_access : 1;
uint8_t channel_privilege_limit : 4;
#else
unsigned char channel_privilege_limit : 4;
unsigned char ipmi_messaging_access : 1;
unsigned char link_auth_access : 1;
unsigned char no_callin_access : 1;
unsigned char __reserved4 : 1;
uint8_t channel_privilege_limit : 4;
uint8_t ipmi_messaging_access : 1;
uint8_t link_auth_access : 1;
uint8_t no_callin_access : 1;
uint8_t __reserved4 : 1;
#endif
} __attribute__ ((packed));

View File

@ -36,10 +36,11 @@ INCLUDES = -I$(top_srcdir)/include
MAINTAINERCLEANFILES = Makefile.in
noinst_LTLIBRARIES = libipmitool.la
libipmitool_la_SOURCES = helper.c ipmi_sdr.c ipmi_sel.c ipmi_sol.c ipmi_isol.c \
ipmi_lanp.c ipmi_fru.c ipmi_chassis.c ipmi_bmc.c log.c \
libipmitool_la_SOURCES = helper.c ipmi_sdr.c ipmi_sel.c ipmi_sol.c ipmi_pef.c \
ipmi_lanp.c ipmi_fru.c ipmi_chassis.c ipmi_mc.c log.c \
dimm_spd.c ipmi_sensor.c ipmi_channel.c ipmi_event.c \
ipmi_session.c ipmi_strings.c ipmi_user.c ipmi_raw.c
ipmi_session.c ipmi_strings.c ipmi_user.c ipmi_raw.c \
ipmi_oem.c ipmi_isol.c
libipmitool_la_LDFLAGS = -export-dynamic
libipmitool_la_LIBADD = -lm
libipmitool_la_DEPENDENCIES =

View File

@ -35,6 +35,8 @@
*/
#include <ipmitool/ipmi.h>
#include <ipmitool/log.h>
#include <ipmitool/helper.h>
#include <ipmitool/ipmi_intf.h>
#include <ipmitool/ipmi_fru.h>
@ -670,12 +672,13 @@ const struct valstr jedec_id5_vals[] = {
{ 0x00, NULL },
};
void ipmi_spd_print(struct ipmi_intf * intf, unsigned char id)
int
ipmi_spd_print(struct ipmi_intf * intf, uint8_t id)
{
struct ipmi_rs * rsp;
struct ipmi_rq req;
struct fru_info fru;
unsigned char spd_data[256], msg_data[4];
uint8_t spd_data[256], msg_data[4];
int len, offset, size;
msg_data[0] = id;
@ -687,14 +690,26 @@ void ipmi_spd_print(struct ipmi_intf * intf, unsigned char id)
req.msg.data_len = 1;
rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode)
return;
if (rsp == NULL) {
printf(" Device not present (No Response)\n");
return -1;
}
if (rsp->ccode > 0) {
printf(" Device not present (%s)\n",
val2str(rsp->ccode, completion_code_vals));
return -1;
}
fru.size = (rsp->data[1] << 8) | rsp->data[0];
fru.access = rsp->data[2] & 0x1;
if (verbose > 1)
printf("fru.size = %d bytes (accessed by %s)\n",
fru.size, fru.access ? "words" : "bytes");
lprintf(LOG_DEBUG, "fru.size = %d bytes (accessed by %s)",
fru.size, fru.access ? "words" : "bytes");
if (fru.size < 1) {
lprintf(LOG_ERR, " Invalid FRU size %d", fru.size);
return -1;
}
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_STORAGE;
@ -711,49 +726,63 @@ void ipmi_spd_print(struct ipmi_intf * intf, unsigned char id)
msg_data[3] = 32;
rsp = intf->sendrecv(intf, &req);
if (!rsp) {
printf(" Error while reading FRU data.\n");
return;
if (rsp == NULL) {
printf(" Device not present (No Response)\n");
return -1;
}
if (rsp->ccode == 0xc3) {
printf(" Timeout while reading FRU data. (Device not present?)\n");
return;
if (rsp->ccode > 0) {
printf(" Device not present (%s)\n",
val2str(rsp->ccode, completion_code_vals));
/* Timeouts are acceptable. No DIMM in the socket */
if (rsp->ccode == 0xc3)
return 1;
return -1;
}
if (rsp->ccode)
break;
len = rsp->data[0];
memcpy(&spd_data[offset], rsp->data + 1, len);
offset += len;
} while (offset < fru.size);
if (verbose)
if (verbose > 1)
printbuf(spd_data, offset, "SPD DATA");
if (offset < 92)
return; /* we need first 91 bytes to do our thing */
return -1; /* we need first 91 bytes to do our thing */
size = spd_data[5] * (spd_data[31] << 2);
printf(" Memory Size : %d MB\n", size);
printf(" Memory Type : %s\n", val2str(spd_data[2], spd_memtype_vals));
printf(" Voltage Intf : %s\n", val2str(spd_data[8], spd_voltage_vals));
printf(" Error Detect/Cor : %s\n", val2str(spd_data[11], spd_config_vals));
printf(" Memory Size : %d MB\n", size);
printf(" Memory Type : %s\n",
val2str(spd_data[2], spd_memtype_vals));
printf(" Voltage Intf : %s\n",
val2str(spd_data[8], spd_voltage_vals));
printf(" Error Detect/Cor : %s\n",
val2str(spd_data[11], spd_config_vals));
/* handle jedec table bank continuation values */
printf(" Manufacturer : ");
printf(" Manufacturer : ");
if (spd_data[64] != 0x7f)
printf("%s\n", val2str(spd_data[64], jedec_id1_vals));
printf("%s\n",
val2str(spd_data[64], jedec_id1_vals));
else {
if (spd_data[65] != 0x7f)
printf("%s\n", val2str(spd_data[65], jedec_id2_vals));
printf("%s\n",
val2str(spd_data[65], jedec_id2_vals));
else {
if (spd_data[66] != 0x7f)
printf("%s\n", val2str(spd_data[66], jedec_id3_vals));
printf("%s\n",
val2str(spd_data[66], jedec_id3_vals));
else {
if (spd_data[67] != 0x7f)
printf("%s\n", val2str(spd_data[67], jedec_id4_vals));
printf("%s\n",
val2str(spd_data[67],
jedec_id4_vals));
else
printf("%s\n", val2str(spd_data[68], jedec_id5_vals));
printf("%s\n",
val2str(spd_data[68],
jedec_id5_vals));
}
}
}
@ -762,6 +791,8 @@ void ipmi_spd_print(struct ipmi_intf * intf, unsigned char id)
char part[19];
memcpy(part, spd_data+73, 18);
part[18] = 0;
printf(" Part Number : %s\n", part);
printf(" Part Number : %s\n", part);
}
return 0;
}

View File

@ -39,6 +39,7 @@
#include <inttypes.h>
#include <signal.h>
#include <string.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
@ -46,23 +47,26 @@
#include <errno.h>
#include <ipmitool/helper.h>
#include <ipmitool/log.h>
uint32_t buf2long(unsigned char * buf)
extern int verbose;
uint32_t buf2long(uint8_t * buf)
{
return (uint32_t)(buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0]);
}
unsigned short buf2short(unsigned char * buf)
uint16_t buf2short(uint8_t * buf)
{
return (unsigned short)(buf[1] << 8 | buf[0]);
return (uint16_t)(buf[1] << 8 | buf[0]);
}
const char * buf2str(unsigned char * buf, int len)
const char * buf2str(uint8_t * buf, int len)
{
static char str[1024];
int i;
if (!len || len > 1024)
if (len <= 0 || len > 1024)
return NULL;
memset(str, 0, 1024);
@ -75,28 +79,31 @@ const char * buf2str(unsigned char * buf, int len)
return (const char *)str;
}
void printbuf(const unsigned char * buf, int len, const char * desc)
void printbuf(const uint8_t * buf, int len, const char * desc)
{
int i;
if (!len)
if (len <= 0)
return;
printf("%s (%d bytes)\n", desc, len);
if (verbose < 1)
return;
fprintf(stderr, "%s (%d bytes)\n", desc, len);
for (i=0; i<len; i++) {
if (((i%16) == 0) && (i != 0))
printf("\n");
printf(" %2.2x", buf[i]);
fprintf(stderr, "\n");
fprintf(stderr, " %2.2x", buf[i]);
}
printf("\n");
fprintf(stderr, "\n");
}
const char * val2str(unsigned short val, const struct valstr *vs)
const char * val2str(uint16_t val, const struct valstr *vs)
{
static char un_str[16];
int i = 0;
while (vs[i].str) {
while (vs[i].str != NULL) {
if (vs[i].val == val)
return vs[i].str;
i++;
@ -108,11 +115,11 @@ const char * val2str(unsigned short val, const struct valstr *vs)
return un_str;
}
unsigned short str2val(const char *str, const struct valstr *vs)
uint16_t str2val(const char *str, const struct valstr *vs)
{
int i = 0;
while (vs[i].str) {
while (vs[i].str != NULL) {
if (!strncasecmp(vs[i].str, str, strlen(str)))
return vs[i].val;
i++;
@ -121,41 +128,30 @@ unsigned short str2val(const char *str, const struct valstr *vs)
return 0;
}
void signal_handler(int sig, void * handler)
/* ipmi_csum - calculate an ipmi checksum
*
* @d: buffer to check
* @s: position in buffer to start checksum from
*/
uint8_t
ipmi_csum(uint8_t * d, int s)
{
struct sigaction act;
if (!sig || !handler)
return;
memset(&act, 0, sizeof(act));
act.sa_handler = handler;
act.sa_flags = 0;
if (sigemptyset(&act.sa_mask) < 0) {
psignal(sig, "unable to empty signal set");
return;
}
if (sigaction(sig, &act, NULL) < 0) {
psignal(sig, "unable to register handler");
return;
}
}
unsigned char ipmi_csum(unsigned char * d, int s)
{
unsigned char c = 0;
uint8_t c = 0;
for (; s > 0; s--, d++)
c += *d;
return -c;
}
/* safely open a file for reading or writing
* file: filename
* rw: read-write flag, 1=write
/* ipmi_open_file - safely open a file for reading or writing
*
* @file: filename
* @rw: read-write flag, 1=write
*
* returns pointer to file handler on success
* returns NULL on error
*/
FILE * ipmi_open_file(const char * file, int rw)
FILE *
ipmi_open_file(const char * file, int rw)
{
struct stat st1, st2;
FILE * fp;
@ -165,51 +161,66 @@ FILE * ipmi_open_file(const char * file, int rw)
if (rw) {
/* does not exist, ok to create */
fp = fopen(file, "w");
if (!fp) {
printf("ERROR: Unable to open file %s for write: %s\n",
file, strerror(errno));
if (fp == NULL) {
lperror(LOG_ERR, "Unable to open file %s "
"for write", file);
return NULL;
}
/* created ok, now return the descriptor */
return fp;
} else {
printf("ERROR: File %s does not exist\n", file);
lprintf(LOG_ERR, "File %s does not exist", file);
return NULL;
}
}
/* it exists - only regular files, not links */
if (!S_ISREG(st1.st_mode)) {
printf("ERROR: File %s has invalid mode: %d\n", file, st1.st_mode);
if (S_ISREG(st1.st_mode) == 0) {
lprintf(LOG_ERR, "File %s has invalid mode: %d",
file, st1.st_mode);
return NULL;
}
/* allow only files with 1 link (itself) */
if (st1.st_nlink != 1) {
printf("ERROR: File %s has invalid link count: %d != 1\n",
lprintf(LOG_ERR, "File %s has invalid link count: %d != 1",
file, (int)st1.st_nlink);
return NULL;
}
fp = fopen(file, rw ? "w+" : "r");
if (!fp) {
printf("ERROR: Unable to open file %s: %s\n",
file, strerror(errno));
if (fp == NULL) {
lperror(LOG_ERR, "Unable to open file %s", file);
return NULL;
}
/* stat again */
if (fstat(fileno(fp), &st2) < 0) {
printf("ERROR: Unable to stat file %s: %s\n",
file, strerror(errno));
lperror(LOG_ERR, "Unable to stat file %s", file);
fclose(fp);
return NULL;
}
/* verify inode, owner, link count */
if (st2.st_ino != st1.st_ino ||
st2.st_uid != st1.st_uid ||
st2.st_nlink != 1) {
printf("ERROR: Unable to verify file %s\n", file);
/* verify inode */
if (st1.st_ino != st2.st_ino) {
lprintf(LOG_ERR, "File %s has invalid inode: %d != %d",
file, st1.st_ino, st2.st_ino);
fclose(fp);
return NULL;
}
/* verify owner */
if (st1.st_uid != st2.st_uid) {
lprintf(LOG_ERR, "File %s has invalid user id: %d != %d",
file, st1.st_uid, st2.st_uid);
fclose(fp);
return NULL;
}
/* verify inode */
if (st2.st_nlink != 1) {
lprintf(LOG_ERR, "File %s has invalid link count: %d != 1",
file, st2.st_nlink);
fclose(fp);
return NULL;
}

View File

@ -37,86 +37,48 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <ipmitool/ipmi.h>
#include <ipmitool/ipmi_intf.h>
#include <ipmitool/helper.h>
#include <ipmitool/log.h>
#include <ipmitool/ipmi_lanp.h>
#include <ipmitool/ipmi_channel.h>
#include <ipmitool/ipmi_strings.h>
#include <ipmitool/ipmi_constants.h>
extern int csv_output;
extern int verbose;
void printf_channel_usage (void);
extern const struct valstr ipmi_authtype_vals[];
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 },
};
/**
* ipmi_1_5_authtypes
*
* Create a string describing the supported authentication types as
* specificed by the parameter n
*/
const char * ipmi_1_5_authtypes(unsigned char n)
static const char *
ipmi_1_5_authtypes(uint8_t n)
{
unsigned int i;
uint32_t i;
static char supportedTypes[128];
bzero(supportedTypes, 128);
i = 0;
while (ipmi_authtype_vals[i].val)
{
if (n & ipmi_authtype_vals[i].val)
{
for (i = 0; ipmi_authtype_vals[i].val != 0; i++) {
if (n & ipmi_authtype_vals[i].val) {
strcat(supportedTypes, ipmi_authtype_vals[i].str);
strcat(supportedTypes, " ");
}
++i;
}
return supportedTypes;
@ -130,16 +92,16 @@ const char * ipmi_1_5_authtypes(unsigned char n)
* return 0 on success
* -1 on failure
*/
int ipmi_get_channel_auth_cap(struct ipmi_intf * intf,
unsigned char channel,
unsigned char priv)
int
ipmi_get_channel_auth_cap(struct ipmi_intf * intf,
uint8_t channel,
uint8_t priv)
{
struct ipmi_rs * rsp;
struct ipmi_rq req;
struct get_channel_auth_cap_rsp auth_cap;
uint8_t msg_data[2];
unsigned char msg_data[2];
msg_data[0] = channel | 0x80; // Ask for IPMI v2 data as well
msg_data[1] = priv;
@ -151,8 +113,7 @@ int ipmi_get_channel_auth_cap(struct ipmi_intf * intf,
rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode)
{
if ((rsp == NULL) || (rsp->ccode > 0)) {
/*
* It's very possible that this failed because we asked for IPMI v2 data
* Ask again, without requesting IPMI v2 data
@ -160,16 +121,19 @@ int ipmi_get_channel_auth_cap(struct ipmi_intf * intf,
msg_data[0] &= 0x7F;
rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode) {
printf("Error:%x Get Channel Authentication Capabilities Command (0x%x)\n",
rsp ? rsp->ccode : 0, channel);
if (rsp == NULL) {
lprintf(LOG_ERR, "Unable to Get Channel Authentication Capabilities");
return -1;
}
if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Get Channel Authentication Capabilities failed: %s",
val2str(rsp->ccode, completion_code_vals));
return -1;
}
}
memcpy(&auth_cap, rsp->data, sizeof(struct get_channel_auth_cap_rsp));
printf("Channel number : %d\n",
auth_cap.channel_number);
printf("IPMI v1.5 auth types : %s\n",
@ -191,8 +155,7 @@ int ipmi_get_channel_auth_cap(struct ipmi_intf * intf,
printf("Anonymous login enabled : %s\n",
(auth_cap.anon_login_enabled) ? "yes" : "no");
if (auth_cap.v20_data_available)
{
if (auth_cap.v20_data_available) {
printf("Channel supports IPMI v1.5 : %s\n",
(auth_cap.ipmiv15_support) ? "yes" : "no");
printf("Channel supports IPMI v2.0 : %s\n",
@ -203,8 +166,7 @@ int ipmi_get_channel_auth_cap(struct ipmi_intf * intf,
* If there is support for an OEM authentication type, there is some
* information.
*/
if (auth_cap.enabled_auth_types & IPMI_1_5_AUTH_TYPE_BIT_OEM)
{
if (auth_cap.enabled_auth_types & IPMI_1_5_AUTH_TYPE_BIT_OEM) {
printf("IANA Number for OEM : %d\n",
auth_cap.oem_id[0] |
auth_cap.oem_id[1] << 8 |
@ -226,11 +188,11 @@ int ipmi_get_channel_auth_cap(struct ipmi_intf * intf,
*
*/
int
ipmi_get_channel_info(struct ipmi_intf * intf, unsigned char channel)
ipmi_get_channel_info(struct ipmi_intf * intf, uint8_t channel)
{
struct ipmi_rs * rsp;
struct ipmi_rq req;
unsigned char rqdata[2];
uint8_t rqdata[2];
struct get_channel_info_rsp channel_info;
struct get_channel_access_rsp channel_access;
@ -241,17 +203,18 @@ ipmi_get_channel_info(struct ipmi_intf * intf, unsigned char channel)
req.msg.data_len = 1;
rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode) {
printf("Error:%x Get Channel Info Command (0x%x)\n",
rsp ? rsp->ccode : 0, channel);
if (rsp == NULL) {
lprintf(LOG_ERR, "Unable to Get Channel Info");
return -1;
}
if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Get Channel Info failed: %s",
val2str(rsp->ccode, completion_code_vals));
return -1;
}
memcpy(&channel_info, rsp->data, sizeof(struct get_channel_info_rsp));
printf("Channel 0x%x info:\n", channel_info.channel_number);
printf(" Channel Medium Type : %s\n",
@ -299,7 +262,13 @@ ipmi_get_channel_info(struct ipmi_intf * intf, unsigned char channel)
req.msg.data_len = 2;
rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode) {
if (rsp == NULL) {
lprintf(LOG_ERR, "Unable to Get Channel Access (volatile)");
return -1;
}
if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Get Channel Access (volatile) failed: %s",
val2str(rsp->ccode, completion_code_vals));
return -1;
}
@ -337,7 +306,13 @@ ipmi_get_channel_info(struct ipmi_intf * intf, unsigned char channel)
rqdata[1] = 0x40; /* 0x40=non-volatile */
rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode) {
if (rsp == NULL) {
lprintf(LOG_ERR, "Unable to Get Channel Access (non-volatile)");
return -1;
}
if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Get Channel Access (non-volatile) failed: %s",
val2str(rsp->ccode, completion_code_vals));
return -1;
}
@ -370,21 +345,19 @@ ipmi_get_channel_info(struct ipmi_intf * intf, unsigned char channel)
break;
}
return 0;
return 0;
}
static int
ipmi_get_user_access(struct ipmi_intf * intf, unsigned char channel, unsigned char userid)
ipmi_get_user_access(struct ipmi_intf * intf, uint8_t channel, uint8_t userid)
{
struct ipmi_rs * rsp;
struct ipmi_rq req1, req2;
unsigned char rqdata[2];
uint8_t rqdata[2];
struct get_user_access_rsp user_access;
int curr_uid, max_uid = 0, init = 1;
ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN);
curr_uid = userid ? userid : 1;
curr_uid = userid ? : 1;
memset(&req1, 0, sizeof(req1));
req1.msg.netfn = IPMI_NETFN_APP;
@ -404,39 +377,53 @@ ipmi_get_user_access(struct ipmi_intf * intf, unsigned char channel, unsigned ch
rqdata[1] = curr_uid & 0x3f;
rsp = intf->sendrecv(intf, &req1);
if (!rsp || rsp->ccode) {
printf("Error:%x Get User Access Command (0x%x)\n",
rsp ? rsp->ccode : 0, channel);
if (rsp == NULL) {
lprintf(LOG_ERR, "Unable to Get User Access (channel %d id %d)",
rqdata[0], rqdata[1]);
return -1;
}
if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Get User Access (channel %d id %d) failed: %s",
rqdata[0], rqdata[1],
val2str(rsp->ccode, completion_code_vals));
return -1;
}
memcpy(&user_access, rsp->data, sizeof(struct get_user_access_rsp));
rqdata[0] = curr_uid & 0x3f;
rsp = intf->sendrecv(intf, &req2);
if (!rsp || rsp->ccode) {
printf("Error:%x Get User Name Command (0x%x)\n",
rsp ? rsp->ccode : 0, channel);
if (rsp == NULL) {
lprintf(LOG_ERR, "Unable to Get User Name (id %d)", rqdata[0]);
return -1;
}
if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Get User Name (id %d) failed: %s",
rqdata[0], val2str(rsp->ccode, completion_code_vals));
return -1;
}
if (init)
{
if (init) {
printf("Maximum User IDs : %d\n", user_access.max_user_ids);
printf("Enabled User IDs : %d\n", user_access.enabled_user_ids);
max_uid = user_access.max_user_ids;
init = 0;
}
printf("\nUser ID : %d\n", curr_uid);
printf("\n");
printf("User ID : %d\n", curr_uid);
printf("User Name : %s\n", rsp->data);
printf("Fixed Name : %s\n", curr_uid <= user_access.fixed_user_ids ? "Yes" : "No");
printf("Access Available : %s\n", user_access.callin_callback ? "callback" : "call-in / callback");
printf("Link Authentication : %sabled\n", user_access.link_auth ? "en" : "dis");
printf("IPMI Messaging : %sabled\n", user_access.ipmi_messaging ? "en" : "dis");
printf("Privilege Level : %s\n", val2str(user_access.privilege_limit, ipmi_privlvl_vals));
printf("Fixed Name : %s\n",
(curr_uid <= user_access.fixed_user_ids) ? "Yes" : "No");
printf("Access Available : %s\n",
(user_access.callin_callback) ? "callback" : "call-in / callback");
printf("Link Authentication : %sabled\n",
(user_access.link_auth) ? "en" : "dis");
printf("IPMI Messaging : %sabled\n",
(user_access.ipmi_messaging) ? "en" : "dis");
printf("Privilege Level : %s\n",
val2str(user_access.privilege_limit, ipmi_privlvl_vals));
curr_uid ++;
@ -445,26 +432,24 @@ ipmi_get_user_access(struct ipmi_intf * intf, unsigned char channel, unsigned ch
return 0;
}
static void
static int
ipmi_set_user_access(struct ipmi_intf * intf, int argc, char ** argv)
{
unsigned char channel, userid;
uint8_t channel, userid;
struct ipmi_rs * rsp;
struct ipmi_rq req;
unsigned char rqdata[2];
uint8_t rqdata[2];
struct get_user_access_rsp user_access;
struct set_user_access_data set_access;
int i;
ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN);
if (argc < 3 || !strncmp(argv[0], "help", 4)) {
if ((argc < 3) || (strncmp(argv[0], "help", 4) == 0)) {
printf_channel_usage();
return;
return 0;
}
channel = (unsigned char)strtol(argv[0], NULL, 0);
userid = (unsigned char)strtol(argv[1], NULL, 0);
channel = (uint8_t)strtol(argv[0], NULL, 0);
userid = (uint8_t)strtol(argv[1], NULL, 0);
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_APP;
@ -476,10 +461,16 @@ ipmi_set_user_access(struct ipmi_intf * intf, int argc, char ** argv)
rqdata[1] = userid & 0x3f;
rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode) {
printf("Error:%x Get User Access Command (0x%x)\n",
rsp ? rsp->ccode : 0, channel);
return;
if (rsp == NULL) {
lprintf(LOG_ERR, "Unable to Get User Access (channel %d id %d)",
rqdata[0], rqdata[1]);
return -1;
}
if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Get User Access (channel %d id %d) failed: %s",
rqdata[0], rqdata[1],
val2str(rsp->ccode, completion_code_vals));
return -1;
}
memcpy(&user_access, rsp->data, sizeof(struct get_user_access_rsp));
@ -495,55 +486,299 @@ ipmi_set_user_access(struct ipmi_intf * intf, int argc, char ** argv)
for (i = 2; i < argc; i ++)
{
if (!strncmp(argv[i], "callin=", 7)) {
set_access.callin_callback = !strncmp (argv[i]+7, "off", 3);
if (strncmp(argv[i], "callin=", 7) == 0) {
set_access.callin_callback = !(strncmp (argv[i]+7, "off", 3));
}
else if (!strncmp(argv[i], "link=", 5)) {
else if (strncmp(argv[i], "link=", 5) == 0) {
set_access.link_auth = strncmp (argv[i]+5, "off", 3);
}
else if (!strncmp(argv[i], "ipmi=", 5)) {
else if (strncmp(argv[i], "ipmi=", 5) == 0) {
set_access.ipmi_messaging = strncmp (argv[i]+5, "off", 3);
}
else if (!strncmp(argv[i], "privilege=", 10)) {
else if (strncmp(argv[i], "privilege=", 10) == 0) {
set_access.privilege_limit = strtol (argv[i]+10, NULL, 0);
}
else {
printf ("Invalid option: %s\n", argv [i]);
return;
return -1;
}
}
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_APP;
req.msg.cmd = IPMI_SET_USER_ACCESS;
req.msg.data = (unsigned char *) &set_access;
req.msg.data = (uint8_t *) &set_access;
req.msg.data_len = 4;
rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode) {
printf("Error:%x Set User Access Command (0x%x)\n",
rsp ? rsp->ccode : 0, channel);
return;
if (rsp == NULL) {
lprintf(LOG_ERR, "Unable to Set User Access (channel %d id %d)",
set_access.channel, set_access.user_id);
return -1;
}
if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Set User Access (channel %d id %d) failed: %s",
set_access.channel, set_access.user_id,
val2str(rsp->ccode, completion_code_vals));
return -1;
}
return;
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
ipmi_get_channel_medium(struct ipmi_intf * intf, uint8_t channel)
{
struct ipmi_rs * rsp;
struct ipmi_rq req;
struct get_channel_info_rsp info;
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_APP;
req.msg.cmd = IPMI_GET_CHANNEL_INFO;
req.msg.data = &channel;
req.msg.data_len = 1;
rsp = intf->sendrecv(intf, &req);
if (rsp == NULL) {
lprintf(LOG_ERR, "Get Channel Info command failed");
return -1;
}
if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Get Channel Info command failed: %s",
val2str(rsp->ccode, completion_code_vals));
return -1;
}
memcpy(&info, rsp->data, sizeof(struct get_channel_info_rsp));
lprintf(LOG_DEBUG, "Channel type: %s",
val2str(info.channel_medium, ipmi_channel_medium_vals));
return info.channel_medium;
}
uint8_t
ipmi_current_channel_medium(struct ipmi_intf * intf)
{
return ipmi_get_channel_medium(intf, 0xE);
}
void
printf_channel_usage()
{
printf("Channel Commands: authcap <channel number> <max privilege>\n");
printf(" getaccess <channel number> [user id]\n");
printf(" setaccess <channel number> <user id> [callin=on|off] [ipmi=on|off] [link=on|off] [privilege=level]\n");
printf(" info [channel number]\n");
printf("\n");
printf("Possible privilege levels are:\n");
printf(" 1 Callback level\n");
printf(" 2 User level\n");
printf(" 3 Operator level\n");
printf(" 4 Administrator level\n");
printf(" 5 OEM Proprietary level\n");
printf(" 15 No access\n");
lprintf(LOG_NOTICE, "Channel Commands: authcap <channel number> <max privilege>");
lprintf(LOG_NOTICE, " getaccess <channel number> [user id]");
lprintf(LOG_NOTICE, " setaccess <channel number> "
"<user id> [callin=on|off] [ipmi=on|off] [link=on|off] [privilege=level]");
lprintf(LOG_NOTICE, " info [channel number]");
lprintf(LOG_NOTICE, " getciphers <all | supported> <ipmi | sol> [channel]\n");
lprintf(LOG_NOTICE, "Possible privilege levels are:");
lprintf(LOG_NOTICE, " 1 Callback level");
lprintf(LOG_NOTICE, " 2 User level");
lprintf(LOG_NOTICE, " 3 Operator level");
lprintf(LOG_NOTICE, " 4 Administrator level");
lprintf(LOG_NOTICE, " 5 OEM Proprietary level");
lprintf(LOG_NOTICE, " 15 No access");
}
@ -552,51 +787,70 @@ ipmi_channel_main(struct ipmi_intf * intf, int argc, char ** argv)
{
int retval = 0;
if (!argc || !strncmp(argv[0], "help", 4))
if ((argc == 0) || (strncmp(argv[0], "help", 4) == 0))
{
printf_channel_usage();
}
else if (!strncmp(argv[0], "authcap", 7))
else if (strncmp(argv[0], "authcap", 7) == 0)
{
if (argc != 3)
printf_channel_usage();
else
retval = ipmi_get_channel_auth_cap(intf,
(unsigned char)strtol(argv[1], NULL, 0),
(unsigned char)strtol(argv[2], NULL, 0));
(uint8_t)strtol(argv[1], NULL, 0),
(uint8_t)strtol(argv[2], NULL, 0));
}
else if (!strncmp(argv[0], "getaccess", 10))
else if (strncmp(argv[0], "getaccess", 10) == 0)
{
if (argc < 2 || argc > 3)
if ((argc < 2) || (argc > 3))
printf_channel_usage();
else {
unsigned char ch = (unsigned char)strtol(argv[1], NULL, 0);
unsigned char id = 0;
uint8_t ch = (uint8_t)strtol(argv[1], NULL, 0);
uint8_t id = 0;
if (argc == 3)
id = (unsigned char)strtol(argv[2], NULL, 0);
id = (uint8_t)strtol(argv[2], NULL, 0);
retval = ipmi_get_user_access(intf, ch, id);
}
}
else if (!strncmp(argv[0], "setaccess", 9))
else if (strncmp(argv[0], "setaccess", 9) == 0)
{
ipmi_set_user_access(intf, argc-1, &(argv[1]));
retval = ipmi_set_user_access(intf, argc-1, &(argv[1]));
}
else if (!strncmp(argv[0], "info", 4))
else if (strncmp(argv[0], "info", 4) == 0)
{
if (argc > 2)
printf_channel_usage();
else {
unsigned char ch = 0xe;
uint8_t ch = 0xe;
if (argc == 2)
ch = (unsigned char)strtol(argv[1], NULL, 0);
ch = (uint8_t)strtol(argv[1], NULL, 0);
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
{
printf("Invalid CHANNEL command: %s\n", argv[0]);
printf_channel_usage();
retval = 1;
retval = -1;
}
return retval;

View File

@ -40,12 +40,14 @@
#include <ipmitool/helper.h>
#include <ipmitool/ipmi.h>
#include <ipmitool/log.h>
#include <ipmitool/ipmi_intf.h>
#include <ipmitool/ipmi_chassis.h>
extern int verbose;
static int ipmi_chassis_power_status(struct ipmi_intf * intf)
static int
ipmi_chassis_power_status(struct ipmi_intf * intf)
{
struct ipmi_rs * rsp;
struct ipmi_rq req;
@ -56,14 +58,19 @@ static int ipmi_chassis_power_status(struct ipmi_intf * intf)
req.msg.data_len = 0;
rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode) {
printf("error in Chassis Status Command\n");
return 0;
if (rsp == NULL) {
lprintf(LOG_ERR, "Unable to get Chassis Power Status");
return -1;
}
if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Get Chassis Power Status failed: %s",
val2str(rsp->ccode, completion_code_vals));
return -1;
}
printf("Chassis Power is %s\n", (rsp->data[0] & 0x1) ? "on" : "off");
return rsp->data[0] & 0x1;
return 0;
}
static const struct valstr ipmi_chassis_power_control_vals[] = {
@ -76,13 +83,12 @@ static const struct valstr ipmi_chassis_power_control_vals[] = {
{ 0x00, NULL },
};
static void ipmi_chassis_power_control(struct ipmi_intf * intf, unsigned char ctl)
static int
ipmi_chassis_power_control(struct ipmi_intf * intf, uint8_t ctl)
{
struct ipmi_rs * rsp;
struct ipmi_rq req;
ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN);
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_CHASSIS;
req.msg.cmd = 0x2;
@ -90,44 +96,51 @@ static void ipmi_chassis_power_control(struct ipmi_intf * intf, unsigned char ct
req.msg.data_len = 1;
rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode) {
printf("Unable to set Chassis Power Control to %s\n",
val2str(ctl, ipmi_chassis_power_control_vals));
} else {
printf("Chassis Power Control: %s\n",
val2str(ctl, ipmi_chassis_power_control_vals));
intf->abort = 1;
if (rsp == NULL) {
lprintf(LOG_ERR, "Unable to set Chassis Power Control to %s",
val2str(ctl, ipmi_chassis_power_control_vals));
return -1;
}
if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Set Chassis Power Control to %s failed: %s",
val2str(ctl, ipmi_chassis_power_control_vals),
val2str(rsp->ccode, completion_code_vals));
return -1;
}
printf("Chassis Power Control: %s\n",
val2str(ctl, ipmi_chassis_power_control_vals));
/* sessions often get lost when changing chassis power */
intf->abort = 1;
return 0;
}
static void ipmi_chassis_identify(struct ipmi_intf * intf, char * arg)
static int
ipmi_chassis_identify(struct ipmi_intf * intf, char * arg)
{
struct ipmi_rq req;
struct ipmi_rs * rsp;
struct {
unsigned char interval;
unsigned char force_on;
uint8_t interval;
uint8_t force_on;
} identify_data;
ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN);
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_CHASSIS;
req.msg.cmd = 0x4;
if (arg) {
if (!strcmp(arg, "force")){
identify_data.interval = 0;
identify_data.force_on = 1;
} else {
identify_data.interval = (unsigned char)atoi(arg);
identify_data.force_on = 0;
}
req.msg.data = (unsigned char *)&identify_data;
if (arg != NULL) {
if (strncmp(arg, "force", 5) == 0) {
identify_data.interval = 0;
identify_data.force_on = 1;
} else {
identify_data.interval = (uint8_t)atoi(arg);
identify_data.force_on = 0;
}
req.msg.data = (uint8_t *)&identify_data;
/* The Force Identify On byte is optional and not
* supported by all devices-- if force is not specified,
* we pass only one data byte; if specified, we pass two
@ -137,34 +150,41 @@ static void ipmi_chassis_identify(struct ipmi_intf * intf, char * arg)
}
rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode) {
printf("ERROR:%x Chassis Identify Command\n", rsp->ccode);
if (identify_data.force_on) {
if (rsp == NULL) {
lprintf(LOG_ERR, "Unable to set Chassis Identify");
return -1;
}
if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Set Chassis Identify failed: %s",
val2str(rsp->ccode, completion_code_vals));
if (identify_data.force_on != 0) {
/* Intel SE7501WV2 F/W 1.2 returns CC 0xC7, but
* the IPMI v1.5 spec does not standardize a CC
* if unsupported, so we warn
*/
printf("Chassis may not support Force Identify On\n");
lprintf(LOG_WARNING, "Chassis may not support Force Identify On\n");
}
return;
return -1;
}
printf("Chassis identify interval: ");
if (!arg) {
if (arg == NULL) {
printf("default (15 seconds)\n");
} else {
if (identify_data.force_on) {
if (identify_data.force_on != 0) {
printf("indefinate\n");
} else {
if (identify_data.interval) {
printf("%i seconds\n", identify_data.interval);
} else {
if (identify_data.interval == 0)
printf("off\n");
}
else
printf("%i seconds\n", identify_data.interval);
}
}
return 0;
}
static void ipmi_chassis_poh(struct ipmi_intf * intf)
static int
ipmi_chassis_poh(struct ipmi_intf * intf)
{
struct ipmi_rs * rsp;
struct ipmi_rq req;
@ -175,17 +195,26 @@ static void ipmi_chassis_poh(struct ipmi_intf * intf)
req.msg.cmd = 0xf;
rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode)
return;
if (rsp == NULL) {
lprintf(LOG_ERR, "Unable to get Chassis Power-On-Hours");
return -1;
}
if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Get Chassis Power-On-Hours failed: %s",
val2str(rsp->ccode, completion_code_vals));
return -1;
}
memcpy(&count, rsp->data+1, 4);
printf("POH Counter : %li hours total (%li days, %li hours)\n",
(long)count, (long)(count / 24), (long)(count % 24));
return 0;
}
static void ipmi_chassis_restart_cause(struct ipmi_intf * intf)
static int
ipmi_chassis_restart_cause(struct ipmi_intf * intf)
{
struct ipmi_rs * rsp;
struct ipmi_rq req;
@ -195,9 +224,15 @@ static void ipmi_chassis_restart_cause(struct ipmi_intf * intf)
req.msg.cmd = 0x7;
rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode)
return;
if (rsp == NULL) {
lprintf(LOG_ERR, "Unable to get Chassis Restart Cause");
return -1;
}
if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Get Chassis Restart Cause failed: %s",
val2str(rsp->ccode, completion_code_vals));
return -1;
}
printf("System restart cause: ");
@ -233,11 +268,14 @@ static void ipmi_chassis_restart_cause(struct ipmi_intf * intf)
printf("power-cycle via PEF\n");
break;
default:
printf("error!\n");
printf("invalid\n");
}
return 0;
}
static void ipmi_chassis_status(struct ipmi_intf * intf)
static int
ipmi_chassis_status(struct ipmi_intf * intf)
{
struct ipmi_rs * rsp;
struct ipmi_rq req;
@ -247,8 +285,15 @@ static void ipmi_chassis_status(struct ipmi_intf * intf)
req.msg.cmd = 0x1;
rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode)
return;
if (rsp == NULL) {
lprintf(LOG_ERR, "Error sending Chassis Status command");
return -1;
}
if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Error sending Chassis Status command: %s",
val2str(rsp->ccode, completion_code_vals));
return -1;
}
/* byte 1 */
printf("System Power : %s\n", (rsp->data[0] & 0x1) ? "on" : "off");
@ -292,31 +337,31 @@ static void ipmi_chassis_status(struct ipmi_intf * intf)
printf("Drive Fault : %s\n", (rsp->data[2] & 0x4) ? "true" : "false");
printf("Cooling/Fan Fault : %s\n", (rsp->data[2] & 0x8) ? "true" : "false");
if (rsp->data_len > 3)
{
/* optional byte 4 */
if (rsp->data[3] == 0) {
printf("Front Panel Control : none\n");
} else {
printf("Sleep Button Disable : %s\n", (rsp->data[3] & 0x80) ? "allowed" : "not allowed");
printf("Diag Button Disable : %s\n", (rsp->data[3] & 0x40) ? "allowed" : "not allowed");
printf("Reset Button Disable : %s\n", (rsp->data[3] & 0x20) ? "allowed" : "not allowed");
printf("Power Button Disable : %s\n", (rsp->data[3] & 0x10) ? "allowed" : "not allowed");
printf("Sleep Button Disabled: %s\n", (rsp->data[3] & 0x80) ? "true" : "false");
printf("Diag Button Disabled : %s\n", (rsp->data[3] & 0x40) ? "true" : "false");
printf("Reset Button Disabled: %s\n", (rsp->data[3] & 0x20) ? "true" : "false");
printf("Power Button Disabled: %s\n", (rsp->data[3] & 0x10) ? "true" : "false");
}
if (rsp->data_len > 3) {
/* optional byte 4 */
if (rsp->data[3] == 0) {
printf("Front Panel Control : none\n");
} else {
printf("Sleep Button Disable : %s\n", (rsp->data[3] & 0x80) ? "allowed" : "not allowed");
printf("Diag Button Disable : %s\n", (rsp->data[3] & 0x40) ? "allowed" : "not allowed");
printf("Reset Button Disable : %s\n", (rsp->data[3] & 0x20) ? "allowed" : "not allowed");
printf("Power Button Disable : %s\n", (rsp->data[3] & 0x10) ? "allowed" : "not allowed");
printf("Sleep Button Disabled: %s\n", (rsp->data[3] & 0x80) ? "true" : "false");
printf("Diag Button Disabled : %s\n", (rsp->data[3] & 0x40) ? "true" : "false");
printf("Reset Button Disabled: %s\n", (rsp->data[3] & 0x20) ? "true" : "false");
printf("Power Button Disabled: %s\n", (rsp->data[3] & 0x10) ? "true" : "false");
}
}
return 0;
}
static void ipmi_chassis_set_bootparam(struct ipmi_intf * intf, unsigned char param, unsigned char * data, int len)
static int
ipmi_chassis_set_bootparam(struct ipmi_intf * intf, uint8_t param, uint8_t * data, int len)
{
struct ipmi_rs * rsp;
struct ipmi_rq req;
unsigned char msg_data[16];
ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN);
uint8_t msg_data[16];
memset(msg_data, 0, 16);
msg_data[0] = param & 0x7f;
@ -329,26 +374,33 @@ static void ipmi_chassis_set_bootparam(struct ipmi_intf * intf, unsigned char pa
req.msg.data_len = len + 1;
rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode) {
printf("Error setting Chassis Boot Parameter %d\n", param);
return;
if (rsp == NULL) {
lprintf(LOG_ERR, "Error setting Chassis Boot Parameter %d", param);
return -1;
}
if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Set Chassis Boot Parameter %d failed: %s",
param, val2str(rsp->ccode, completion_code_vals));
return -1;
}
printf("Chassis Set Boot Param %d to %s\n", param, data);
lprintf(LOG_DEBUG, "Chassis Set Boot Parameter %d to %s", param, buf2str(data, len));
return 0;
}
static void ipmi_chassis_get_bootparam(struct ipmi_intf * intf, char * arg)
static int
ipmi_chassis_get_bootparam(struct ipmi_intf * intf, char * arg)
{
struct ipmi_rs * rsp;
struct ipmi_rq req;
unsigned char msg_data[3];
uint8_t msg_data[3];
if (!arg)
return;
if (arg == NULL)
return -1;
memset(msg_data, 0, 3);
msg_data[0] = (unsigned char)atoi(arg) & 0x7f;
msg_data[0] = (uint8_t)atoi(arg) & 0x7f;
msg_data[1] = 0;
msg_data[2] = 0;
@ -359,8 +411,15 @@ static void ipmi_chassis_get_bootparam(struct ipmi_intf * intf, char * arg)
req.msg.data_len = 3;
rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode)
return;
if (rsp == NULL) {
lprintf(LOG_ERR, "Error Getting Chassis Boot Parameter %s", arg);
return -1;
}
if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Get Chassis Boot Parameter %s failed: %s",
arg, val2str(rsp->ccode, completion_code_vals));
return -1;
}
if (verbose > 2)
printbuf(rsp->data, rsp->data_len, "Boot Option");
@ -371,51 +430,65 @@ static void ipmi_chassis_get_bootparam(struct ipmi_intf * intf, char * arg)
printf("Boot parameter data: %s\n", buf2str(rsp->data+2, rsp->data_len - 2));
}
static void ipmi_chassis_set_bootflag(struct ipmi_intf * intf, char * arg)
static int
ipmi_chassis_set_bootdev(struct ipmi_intf * intf, char * arg)
{
unsigned char flags[5];
uint8_t flags[5];
int rc = 0;
ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN);
if (!arg) {
printf("Error: no bootflag argument supplied\n");
return;
if (arg == NULL) {
lprintf(LOG_ERR, "No argument supplied");
return -1;
}
if (!strncmp(arg, "force_pxe", 9)) {
flags[1] = 0x04; // 00000100
}
else if (!strncmp(arg, "force_disk", 10)) {
flags[1] = 0x08; // 00001000
}
else if (!strncmp(arg, "force_diag", 10)) {
flags[1] = 0x10; // 00010000
}
else if (!strncmp(arg, "force_cdrom", 11)) {
flags[1] = 0x14; // 00010100
}
else if (!strncmp(arg, "force_floppy", 12)) {
flags[1] = 0x3c; // 00111100
}
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;
else if (strncmp(arg, "disk", 4) == 0 ||
strncmp(arg, "force_disk", 10) == 0)
flags[1] = 0x08;
else if (strncmp(arg, "safe", 4) == 0 ||
strncmp(arg, "force_safe", 10) == 0)
flags[1] = 0x0c;
else if (strncmp(arg, "diag", 4) == 0 ||
strncmp(arg, "force_diag", 10) == 0)
flags[1] = 0x10;
else if (strncmp(arg, "cdrom", 5) == 0 ||
strncmp(arg, "force_cdrom", 11) == 0)
flags[1] = 0x14;
else if (strncmp(arg, "floppy", 6) == 0 ||
strncmp(arg, "force_floppy", 12) == 0)
flags[1] = 0x3c;
else if (strncmp(arg, "bios", 4) == 0 ||
strncmp(arg, "force_bios", 10) == 0)
flags[1] = 0x18;
else {
printf("Invalid bootflag: %s\n", arg);
return;
lprintf(LOG_ERR, "Invalid argument: %s", arg);
return -1;
}
flags[0] = 0x80; /* set flag valid bit */
ipmi_chassis_set_bootparam(intf, 5, flags, 5);
flags[0] = 0x08; /* don't automatically clear boot flag valid bit in 60 seconds */
ipmi_chassis_set_bootparam(intf, 3, flags, 1);
/* set flag valid bit */
flags[0] = 0x80;
rc = ipmi_chassis_set_bootparam(intf, 5, flags, 5);
if (rc == 0)
printf("Set Boot Device to %s\n", arg);
return rc;
}
static void ipmi_chassis_power_policy(struct ipmi_intf * intf, unsigned char policy)
static int
ipmi_chassis_power_policy(struct ipmi_intf * intf, uint8_t policy)
{
struct ipmi_rs * rsp;
struct ipmi_rq req;
ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN);
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_CHASSIS;
req.msg.cmd = 0x6;
@ -423,14 +496,15 @@ static void ipmi_chassis_power_policy(struct ipmi_intf * intf, unsigned char pol
req.msg.data_len = 1;
rsp = intf->sendrecv(intf, &req);
if (!rsp)
return;
if (rsp->ccode > 0) {
printf("BMC Power Restore Policy command failed: %s\n",
val2str(rsp->ccode, completion_code_vals));
return;
if (rsp == NULL) {
lprintf(LOG_ERR, "Error in Power Restore Policy command");
return -1;
}
if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Power Restore Policy command failed: %s",
val2str(rsp->ccode, completion_code_vals));
return -1;
}
if (policy == IPMI_CHASSIS_POLICY_NO_CHANGE) {
printf("Supported chassis power policy: ");
@ -458,121 +532,139 @@ static void ipmi_chassis_power_policy(struct ipmi_intf * intf, unsigned char pol
printf("unknown\n");
}
}
return 0;
}
int ipmi_chassis_main(struct ipmi_intf * intf, int argc, char ** argv)
int
ipmi_chassis_main(struct ipmi_intf * intf, int argc, char ** argv)
{
if (!argc || !strncmp(argv[0], "help", 4)) {
printf("Chassis Commands: status, power, identify, policy, restart_cause, poh\n");
return 0;
}
else if (!strncmp(argv[0], "status", 6)) {
ipmi_chassis_status(intf);
}
else if (!strncmp(argv[0], "power", 5)) {
unsigned char ctl = 0;
int rc = 0;
if (argc < 2 || !strncmp(argv[1], "help", 4)) {
printf("chassis power Commands: status, on, off, cycle, reset, diag, soft\n");
if ((argc == 0) || (strncmp(argv[0], "help", 4) == 0)) {
lprintf(LOG_NOTICE, "Chassis Commands: status, power, identify, policy, restart_cause, poh, bootdev");
}
else if (strncmp(argv[0], "status", 6) == 0) {
rc = ipmi_chassis_status(intf);
}
else if (strncmp(argv[0], "power", 5) == 0) {
uint8_t ctl = 0;
if ((argc < 2) || (strncmp(argv[1], "help", 4) == 0)) {
lprintf(LOG_NOTICE, "chassis power Commands: status, on, off, cycle, reset, diag, soft");
return 0;
}
if (!strncmp(argv[1], "status", 6)) {
ipmi_chassis_power_status(intf);
return 0;
if (strncmp(argv[1], "status", 6) == 0) {
rc = ipmi_chassis_power_status(intf);
return rc;
}
if (!strncmp(argv[1], "up", 2) || !strncmp(argv[1], "on", 2))
if ((strncmp(argv[1], "up", 2) == 0) || (strncmp(argv[1], "on", 2) == 0))
ctl = IPMI_CHASSIS_CTL_POWER_UP;
else if (!strncmp(argv[1], "down", 4) || !strncmp(argv[1], "off", 3))
else if ((strncmp(argv[1], "down", 4) == 0) || (strncmp(argv[1], "off", 3) == 0))
ctl = IPMI_CHASSIS_CTL_POWER_DOWN;
else if (!strncmp(argv[1], "cycle", 5))
else if (strncmp(argv[1], "cycle", 5) == 0)
ctl = IPMI_CHASSIS_CTL_POWER_CYCLE;
else if (!strncmp(argv[1], "reset", 5))
else if (strncmp(argv[1], "reset", 5) == 0)
ctl = IPMI_CHASSIS_CTL_HARD_RESET;
else if (!strncmp(argv[1], "diag", 5))
else if (strncmp(argv[1], "diag", 4) == 0)
ctl = IPMI_CHASSIS_CTL_PULSE_DIAG;
else if (!strncmp (argv[1], "acpi", 4) || !strncmp(argv[1], "soft", 4))
else if ((strncmp(argv[1], "acpi", 4) == 0) || (strncmp(argv[1], "soft", 4) == 0))
ctl = IPMI_CHASSIS_CTL_ACPI_SOFT;
else {
printf("Invalid chassis power command: %s\n", argv[1]);
lprintf(LOG_ERR, "Invalid chassis power command: %s", argv[1]);
return -1;
}
ipmi_chassis_power_control(intf, ctl);
rc = ipmi_chassis_power_control(intf, ctl);
}
else if (!strncmp(argv[0], "identify", 8)) {
else if (strncmp(argv[0], "identify", 8) == 0) {
if (argc < 2) {
ipmi_chassis_identify(intf, NULL);
rc = ipmi_chassis_identify(intf, NULL);
}
else if (!strncmp(argv[1], "help", 4)) {
printf("chassis identify <interval>\n");
printf(" default is 15 seconds\n");
printf(" 0 to turn off\n");
printf(" force to turn on indefinitely\n");
else if (strncmp(argv[1], "help", 4) == 0) {
lprintf(LOG_NOTICE, "chassis identify <interval>");
lprintf(LOG_NOTICE, " default is 15 seconds");
lprintf(LOG_NOTICE, " 0 to turn off");
lprintf(LOG_NOTICE, " force to turn on indefinitely");
} else {
ipmi_chassis_identify(intf, argv[1]);
rc = ipmi_chassis_identify(intf, argv[1]);
}
}
else if (!strncmp(argv[0], "poh", 3)) {
ipmi_chassis_poh(intf);
else if (strncmp(argv[0], "poh", 3) == 0) {
rc = ipmi_chassis_poh(intf);
}
else if (!strncmp(argv[0], "restart_cause", 13)) {
ipmi_chassis_restart_cause(intf);
else if (strncmp(argv[0], "restart_cause", 13) == 0) {
rc = ipmi_chassis_restart_cause(intf);
}
else if (!strncmp(argv[0], "policy", 4)) {
if (argc < 2 || !strncmp(argv[1], "help", 4)) {
printf("chassis policy <state>\n");
printf(" list : return supported policies\n");
printf(" always-on : turn on when power is restored\n");
printf(" previous : return to previous state when power is restored\n");
printf(" always-off : stay off after power is restored\n");
else if (strncmp(argv[0], "policy", 4) == 0) {
if ((argc < 2) || (strncmp(argv[1], "help", 4) == 0)) {
lprintf(LOG_NOTICE, "chassis policy <state>");
lprintf(LOG_NOTICE, " list : return supported policies");
lprintf(LOG_NOTICE, " always-on : turn on when power is restored");
lprintf(LOG_NOTICE, " previous : return to previous state when power is restored");
lprintf(LOG_NOTICE, " always-off : stay off after power is restored");
} else {
unsigned char ctl;
if (!strncmp(argv[1], "list", 4))
uint8_t ctl;
if (strncmp(argv[1], "list", 4) == 0)
ctl = IPMI_CHASSIS_POLICY_NO_CHANGE;
else if (!strncmp(argv[1], "always-on", 9))
else if (strncmp(argv[1], "always-on", 9) == 0)
ctl = IPMI_CHASSIS_POLICY_ALWAYS_ON;
else if (!strncmp(argv[1], "previous", 8))
else if (strncmp(argv[1], "previous", 8) == 0)
ctl = IPMI_CHASSIS_POLICY_PREVIOUS;
else if (!strncmp(argv[1], "always-off", 10))
else if (strncmp(argv[1], "always-off", 10) == 0)
ctl = IPMI_CHASSIS_POLICY_ALWAYS_OFF;
else {
printf("invalid chassis policy: %s\n", argv[1]);
lprintf(LOG_ERR, "Invalid chassis policy: %s", argv[1]);
return -1;
}
ipmi_chassis_power_policy(intf, ctl);
rc = ipmi_chassis_power_policy(intf, ctl);
}
}
else if (!strncmp(argv[0], "bootparam", 7)) {
if (argc < 3 || !strncmp(argv[1], "help", 4)) {
printf("bootparam get|set <option> [value ...]\n");
else if (strncmp(argv[0], "bootparam", 9) == 0) {
if ((argc < 3) || (strncmp(argv[1], "help", 4) == 0)) {
lprintf(LOG_NOTICE, "bootparam get <param #>");
lprintf(LOG_NOTICE, "bootparam set bootflag <flag>");
lprintf(LOG_NOTICE, " force_pxe : Force PXE boot");
lprintf(LOG_NOTICE, " force_disk : Force boot from default Hard-drive");
lprintf(LOG_NOTICE, " force_safe : Force boot from default Hard-drive, request Safe Mode");
lprintf(LOG_NOTICE, " force_diag : Force boot from Diagnostic Partition");
lprintf(LOG_NOTICE, " force_cdrom : Force boot from CD/DVD");
lprintf(LOG_NOTICE, " force_bios : Force boot into BIOS Setup");
}
else {
if (!strncmp(argv[1], "get", 3)) {
ipmi_chassis_get_bootparam(intf, argv[2]);
if (strncmp(argv[1], "get", 3) == 0) {
rc = ipmi_chassis_get_bootparam(intf, argv[2]);
}
else if (!strncmp(argv[1], "set", 3)) {
else if (strncmp(argv[1], "set", 3) == 0) {
if (argc < 4) {
printf("bootparam set <option> [value ...]\n");
lprintf(LOG_NOTICE, "bootparam set <option> [value ...]");
} else {
if (!strncmp(argv[2], "bootflag", 8)) {
ipmi_chassis_set_bootflag(intf, argv[3]);
}
else {
printf("bootparam set <option> [value ...]\n");
}
if (strncmp(argv[2], "bootflag", 8) == 0)
rc = ipmi_chassis_set_bootdev(intf, argv[3]);
else
lprintf(LOG_NOTICE, "bootparam set <option> [value ...]");
}
}
else {
printf("bootparam get|set <option> [value]\n");
}
else
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 {
printf("Invalid Chassis command: %s\n", argv[0]);
lprintf(LOG_ERR, "Invalid Chassis command: %s", argv[0]);
return -1;
}
return 0;
return rc;
}

View File

@ -37,100 +37,236 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <ctype.h>
#include <ipmitool/ipmi.h>
#include <ipmitool/ipmi_intf.h>
#include <ipmitool/helper.h>
#include <ipmitool/log.h>
#include <ipmitool/ipmi_sel.h>
#include <ipmitool/ipmi_strings.h>
#include <ipmitool/ipmi_channel.h>
static int
ipmi_send_platform_event(struct ipmi_intf * intf, int num)
{
struct ipmi_rs * rsp;
struct ipmi_rq req;
unsigned char rqdata[8];
ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN);
uint8_t rqdata[8];
uint8_t chmed;
int p = 0;
memset(&req, 0, sizeof(req));
memset(rqdata, 0, 8);
printf("Sending ");
/* IPMB/LAN/etc */
switch (num) {
case 1: /* temperature */
printf("Temperature - Upper Critical - Going High");
rqdata[0] = 0x04; /* EvMRev */
rqdata[1] = 0x01; /* Sensor Type */
rqdata[2] = 0x30; /* Sensor # */
rqdata[3] = 0x01; /* Event Dir / Event Type */
rqdata[4] = 0x59; /* Event Data 1 */
rqdata[5] = 0x00; /* Event Data 2 */
rqdata[6] = 0x00; /* Event Data 3 */
break;
case 2: /* voltage error */
printf("Voltage Threshold - Lower Critical - Going Low");
rqdata[0] = 0x04; /* EvMRev */
rqdata[1] = 0x02; /* Sensor Type */
rqdata[2] = 0x60; /* Sensor # */
rqdata[3] = 0x01; /* Event Dir / Event Type */
rqdata[4] = 0x52; /* Event Data 1 */
rqdata[5] = 0x00; /* Event Data 2 */
rqdata[6] = 0x00; /* Event Data 3 */
break;
case 3: /* correctable ECC */
printf("Memory - Correctable ECC");
rqdata[0] = 0x04; /* EvMRev */
rqdata[1] = 0x0c; /* Sensor Type */
rqdata[2] = 0x01; /* Sensor # */
rqdata[3] = 0x6f; /* Event Dir / Event Type */
rqdata[4] = 0x00; /* Event Data 1 */
rqdata[5] = 0x00; /* Event Data 2 */
rqdata[6] = 0x00; /* Event Data 3 */
break;
default:
printf("Invalid event number: %d\n", num);
return -1;
}
printf(" event to BMC\n");
req.msg.netfn = IPMI_NETFN_SE;
req.msg.cmd = 0x02;
req.msg.data = rqdata;
req.msg.data_len = 7;
chmed = ipmi_current_channel_medium(intf);
if (chmed == IPMI_CHANNEL_MEDIUM_SYSTEM) {
/* system interface, need extra generator ID */
req.msg.data_len = 8;
rqdata[p++] = 0x20;
}
/* IPMB/LAN/etc */
switch (num) {
case 1: /* temperature */
printf("Sending SAMPLE event: Temperature - "
"Upper Critical - Going High\n");
rqdata[p++] = 0x04; /* EvMRev */
rqdata[p++] = 0x01; /* Sensor Type */
rqdata[p++] = 0x30; /* Sensor # */
rqdata[p++] = 0x01; /* Event Dir / Event Type */
rqdata[p++] = 0x59; /* Event Data 1 */
rqdata[p++] = 0x00; /* Event Data 2 */
rqdata[p++] = 0x00; /* Event Data 3 */
break;
case 2: /* voltage error */
printf("Sending SAMPLE event: Voltage Threshold - "
"Lower Critical - Going Low\n");
rqdata[p++] = 0x04; /* EvMRev */
rqdata[p++] = 0x02; /* Sensor Type */
rqdata[p++] = 0x60; /* Sensor # */
rqdata[p++] = 0x01; /* Event Dir / Event Type */
rqdata[p++] = 0x52; /* Event Data 1 */
rqdata[p++] = 0x00; /* Event Data 2 */
rqdata[p++] = 0x00; /* Event Data 3 */
break;
case 3: /* correctable ECC */
printf("Sending SAMPLE event: Memory - Correctable ECC\n");
rqdata[p++] = 0x04; /* EvMRev */
rqdata[p++] = 0x0c; /* Sensor Type */
rqdata[p++] = 0x53; /* Sensor # */
rqdata[p++] = 0x6f; /* Event Dir / Event Type */
rqdata[p++] = 0x00; /* Event Data 1 */
rqdata[p++] = 0x00; /* Event Data 2 */
rqdata[p++] = 0x00; /* Event Data 3 */
break;
default:
lprintf(LOG_ERR, "Invalid event number: %d", num);
return -1;
}
rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode) {
printf("Error:%x Platform Event Message Command\n", rsp?rsp->ccode:0);
if (rsp == NULL) {
lprintf(LOG_ERR, "Platform Event Message command failed");
return -1;
}
else if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Platform Event Message command failed: %s",
val2str(rsp->ccode, completion_code_vals));
return -1;
}
return 0;
}
int ipmi_event_main(struct ipmi_intf * intf, int argc, char ** argv)
static int
ipmi_event_fromfile(struct ipmi_intf * intf, char * file)
{
unsigned char c;
FILE * fp;
struct ipmi_rs * rsp;
struct ipmi_rq req;
struct sel_event_record sel_event;
uint8_t rqdata[8];
char buf[1024];
char * ptr, * tok;
int i, j;
uint8_t chmed;
int rc = 0;
if (!argc || !strncmp(argv[0], "help", 4)) {
printf("usage: event <num>\n");
printf(" 1 : Temperature - Upper Critical - Going High\n");
printf(" 2 : Voltage Threshold - Lower Critical - Going Low\n");
printf(" 3 : Memory - Correctable ECC\n");
} else {
c = (unsigned char)strtol(argv[0], NULL, 0);
ipmi_send_platform_event(intf, c);
if (file == NULL)
return -1;
memset(rqdata, 0, 8);
/* setup Platform Event Message command */
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_SE;
req.msg.cmd = 0x02;
req.msg.data = rqdata;
req.msg.data_len = 7;
chmed = ipmi_current_channel_medium(intf);
if (chmed == IPMI_CHANNEL_MEDIUM_SYSTEM) {
/* system interface, need extra generator ID */
rqdata[0] = 0x20;
req.msg.data_len = 8;
}
return 0;
fp = ipmi_open_file_read(file);
if (fp == NULL)
return -1;
while (feof(fp) == 0) {
if (fgets(buf, 1024, fp) == NULL)
continue;
/* clip off optional comment tail indicated by # */
ptr = strchr(buf, '#');
if (ptr)
*ptr = '\0';
else
ptr = buf + strlen(buf);
/* clip off trailing and leading whitespace */
ptr--;
while (isspace(*ptr) && ptr >= buf)
*ptr-- = '\0';
ptr = buf;
while (isspace(*ptr))
ptr++;
if (strlen(ptr) == 0)
continue;
/* parse the event, 7 bytes with optional comment */
/* 0x00 0x00 0x00 0x00 0x00 0x00 0x00 # event */
i = 0;
tok = strtok(ptr, " ");
while (tok) {
if (i == 7)
break;
j = i++;
if (chmed == IPMI_CHANNEL_MEDIUM_SYSTEM)
j++;
rqdata[j] = (uint8_t)strtol(tok, NULL, 0);
tok = strtok(NULL, " ");
}
if (i < 7) {
lprintf(LOG_ERR, "Invalid Event: %s",
buf2str(rqdata, sizeof(rqdata)));
continue;
}
memset(&sel_event, 0, sizeof(struct sel_event_record));
sel_event.record_id = 0;
sel_event.gen_id = 2;
j = (chmed == IPMI_CHANNEL_MEDIUM_SYSTEM) ? 1 : 0;
sel_event.evm_rev = rqdata[j++];
sel_event.sensor_type = rqdata[j++];
sel_event.sensor_num = rqdata[j++];
sel_event.event_type = rqdata[j] & 0x7f;
sel_event.event_dir = (rqdata[j++] & 0x80) >> 7;
sel_event.event_data[0] = rqdata[j++];
sel_event.event_data[1] = rqdata[j++];
sel_event.event_data[2] = rqdata[j++];
ipmi_sel_print_std_entry(&sel_event);
rsp = intf->sendrecv(intf, &req);
if (rsp == NULL) {
lprintf(LOG_ERR, "Platform Event Message command failed");
rc = -1;
}
else if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Platform Event Message command failed: %s",
val2str(rsp->ccode, completion_code_vals));
rc = -1;
}
}
fclose(fp);
return rc;
}
int
ipmi_event_main(struct ipmi_intf * intf, int argc, char ** argv)
{
uint8_t c;
int rc = 0;
if (argc == 0 || strncmp(argv[0], "help", 4) == 0) {
lprintf(LOG_NOTICE, "usage: event <num>");
lprintf(LOG_NOTICE, " 1 : Temperature - Upper Critical - Going High");
lprintf(LOG_NOTICE, " 2 : Voltage Threshold - Lower Critical - Going Low");
lprintf(LOG_NOTICE, " 3 : Memory - Correctable ECC");
lprintf(LOG_NOTICE, "usage: event file <filename>");
lprintf(LOG_NOTICE, " Will read list of events from file");
return 0;
}
if (strncmp(argv[0], "file", 4) == 0) {
if (argc < 2) {
lprintf(LOG_NOTICE, "usage: event file <filename>\n");
rc = -1;
} else {
rc = ipmi_event_fromfile(intf, argv[1]);
}
} else {
c = (uint8_t)strtol(argv[0], NULL, 0);
rc = ipmi_send_platform_event(intf, c);
}
return rc;
}

File diff suppressed because it is too large Load Diff

View File

@ -39,13 +39,24 @@
#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)
static int ipmi_isol_setup(struct ipmi_intf * intf, char baudsetting)
{
struct ipmi_rs * rsp;
struct ipmi_rq req;
@ -65,17 +76,17 @@ static int ipmi_isol_setup(struct ipmi_intf * intf)
req.msg.data_len = 3;
rsp = intf->sendrecv(intf, &req);
if (!rsp) {
printf("Error in Set ISOL Config Command\n");
if (rsp == NULL) {
lprintf(LOG_ERR, "Error in Set ISOL Config Command");
return -1;
}
if (rsp->ccode == 0xc1) {
printf("Serial Over Lan not supported!\n");
lprintf(LOG_ERR, "IPMI v1.5 Serial Over Lan (ISOL) not supported!");
return -1;
}
if (rsp->ccode) {
printf("Set Serial Over Lan Config returned %x\n", rsp->ccode);
if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Error in Set ISOL Config Command: %s",
val2str(rsp->ccode, completion_code_vals));
return -1;
}
@ -90,8 +101,13 @@ static int ipmi_isol_setup(struct ipmi_intf * intf)
req.msg.data_len = 4;
rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode) {
printf("Error:%x in Get ISOL Config command\n", rsp?rsp->ccode:0);
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;
}
@ -108,8 +124,13 @@ static int ipmi_isol_setup(struct ipmi_intf * intf)
req.msg.data_len = 3;
rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode) {
printf("Error:%x in Set ISOL Config (Authentication) command\n", rsp?rsp->ccode:0);
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;
}
@ -118,27 +139,57 @@ static int ipmi_isol_setup(struct ipmi_intf * intf)
memset(data, 0, 6);
data[0] = 0x00;
data[1] = ISOL_BAUD_RATE_PARAM;
data[2] = ISOL_PREFERRED_BAUD_RATE;
data[2] = baudsetting;
req.msg.cmd = SET_ISOL_CONFIG;
req.msg.data_len = 3;
rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode) {
printf("Error:%x in Set ISOL Config (Baud Rate) command\n", rsp?rsp->ccode:0);
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)
{
if (!argc || !strncmp(argv[0], "help", 4)) {
printf("ISOL Commands: setup\n");
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;
}
else if (!strncmp(argv[0], "setup", 5)) {
ipmi_isol_setup(intf);
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 0;
return ret;
}

File diff suppressed because it is too large Load Diff

View File

@ -39,41 +39,26 @@
#include <stdio.h>
#include <ipmitool/helper.h>
#include <ipmitool/log.h>
#include <ipmitool/ipmi.h>
#include <ipmitool/ipmi_intf.h>
#include <ipmitool/ipmi_bmc.h>
#include <ipmitool/ipmi_mc.h>
#include <ipmitool/ipmi_strings.h>
extern int verbose;
const struct valstr completion_code_vals[] = {
{ 0x00, "Command completed normally" },
{ 0xc0, "Node busy" },
{ 0xc1, "Invalid command" },
{ 0xc2, "Invalid command on LUN" },
{ 0xc3, "Timeout" },
{ 0xc4, "Out of space" },
{ 0xc5, "Reservation cancelled or invalid" },
{ 0xc6, "Request data truncated" },
{ 0xc7, "Request data length invalid" },
{ 0xc8, "Request data field length limit exceeded" },
{ 0xc9, "Parameter out of range" },
{ 0xca, "Cannot return number of requested data bytes" },
{ 0xcb, "Requested sensor, data, or record not found" },
{ 0xcc, "Invalid data field in request" },
{ 0xcd, "Command illegal for specified sensor or record type" },
{ 0xce, "Command response could not be provided" },
{ 0xcf, "Cannot execute duplicated request" },
{ 0xd0, "SDR Repository in update mode" },
{ 0xd1, "Device firmeware in update mode" },
{ 0xd2, "BMC initialization in progress" },
{ 0xd3, "Destination unavailable" },
{ 0xd4, "Insufficient priviledge level" },
{ 0xd5, "Command not supported in present state" },
{ 0xff, "Unspecified error" },
{ 0x00, NULL }
};
static int ipmi_bmc_reset(struct ipmi_intf * intf, int cmd)
/* ipmi_mc_reset - attempt to reset an MC
*
* @intf: ipmi interface
* @cmd: reset command to send
* BMC_WARM_RESET or
* BMC_COLD_RESET
*
* returns 0 on success
* returns -1 on error
*/
static int
ipmi_mc_reset(struct ipmi_intf * intf, int cmd)
{
struct ipmi_rs * rsp;
struct ipmi_rq req;
@ -84,12 +69,13 @@ static int ipmi_bmc_reset(struct ipmi_intf * intf, int cmd)
req.msg.data_len = 0;
rsp = intf->sendrecv(intf, &req);
if (!rsp) {
printf("Error in BMC Reset Command\n");
if (rsp == NULL) {
lprintf(LOG_ERR, "Reset command failed");
return -1;
}
if (rsp->ccode) {
printf("BMC Reset Command returned %x\n", rsp->ccode);
if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Reset command failed: %s",
val2str(rsp->ccode, completion_code_vals));
return -1;
}
@ -98,23 +84,23 @@ static int ipmi_bmc_reset(struct ipmi_intf * intf, int cmd)
struct bmc_enables_data {
#if WORDS_BIGENDIAN
unsigned char oem2 : 1;
unsigned char oem1 : 1;
unsigned char oem0 : 1;
unsigned char __reserved : 1;
unsigned char system_event_log : 1;
unsigned char event_msgbuf : 1;
unsigned char event_msgbuf_intr : 1;
unsigned char receive_msg_intr : 1;
uint8_t oem2 : 1;
uint8_t oem1 : 1;
uint8_t oem0 : 1;
uint8_t __reserved : 1;
uint8_t system_event_log : 1;
uint8_t event_msgbuf : 1;
uint8_t event_msgbuf_intr : 1;
uint8_t receive_msg_intr : 1;
#else
unsigned char receive_msg_intr : 1;
unsigned char event_msgbuf_intr : 1;
unsigned char event_msgbuf : 1;
unsigned char system_event_log : 1;
unsigned char __reserved : 1;
unsigned char oem0 : 1;
unsigned char oem1 : 1;
unsigned char oem2 : 1;
uint8_t receive_msg_intr : 1;
uint8_t event_msgbuf_intr : 1;
uint8_t event_msgbuf : 1;
uint8_t system_event_log : 1;
uint8_t __reserved : 1;
uint8_t oem0 : 1;
uint8_t oem1 : 1;
uint8_t oem2 : 1;
#endif
} __attribute__ ((packed));
@ -122,71 +108,71 @@ struct bitfield_data {
const char * name;
const char * desc;
uint32_t mask;
int write;
};
struct bitfield_data bmc_enables_bf[] = {
struct bitfield_data mc_enables_bf[] = {
{
name: "recv_msg_intr",
desc: "Receive Message Queue Interrupt",
mask: 1<<0,
write: 1,
},
{
name: "event_msg_intr",
desc: "Event Message Buffer Full Interrupt",
mask: 1<<1,
write: 1,
},
{
name: "event_msg",
desc: "Event Message Buffer",
mask: 1<<2,
write: 1,
},
{
name: "system_event_log",
desc: "System Event Logging",
mask: 1<<3,
write: 1,
},
{
name: "oem0",
desc: "OEM 0",
mask: 1<<5,
write: 1,
},
{
name: "oem1",
desc: "OEM 1",
mask: 1<<6,
write: 1,
},
{
name: "oem2",
desc: "OEM 2",
mask: 1<<7,
write: 1,
},
{ NULL },
};
static void printf_bmc_usage()
static void
printf_mc_usage()
{
struct bitfield_data * bf;
printf("BMC Commands:\n");
printf("MC Commands:\n");
printf(" reset <warm|cold>\n");
printf(" info\n");
printf(" getenables\n");
printf(" setenables <option=on|off> ...\n");
for (bf = bmc_enables_bf; bf->name; bf++) {
if (!bf->write)
continue;
for (bf = mc_enables_bf; bf->name != NULL; bf++) {
printf(" %-20s %s\n", bf->name, bf->desc);
}
}
static int ipmi_bmc_get_enables(struct ipmi_intf * intf)
/* ipmi_mc_get_enables - print out MC enables
*
* @intf: ipmi inteface
*
* returns 0 on success
* returns -1 on error
*/
static int
ipmi_mc_get_enables(struct ipmi_intf * intf)
{
struct ipmi_rs * rsp;
struct ipmi_rq req;
@ -197,17 +183,17 @@ static int ipmi_bmc_get_enables(struct ipmi_intf * intf)
req.msg.cmd = BMC_GET_GLOBAL_ENABLES;
rsp = intf->sendrecv(intf, &req);
if (!rsp) {
printf("Error in BMC Get Global Enables Command\n");
if (rsp == NULL) {
lprintf(LOG_ERR, "Get Global Enables command failed");
return -1;
}
if (rsp->ccode) {
printf("BMC Get Global Enables command failed: %s\n",
if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Get Global Enables command failed: %s",
val2str(rsp->ccode, completion_code_vals));
return -1;
}
for (bf = bmc_enables_bf; bf->name; bf++) {
for (bf = mc_enables_bf; bf->name != NULL; bf++) {
printf("%-40s : %sabled\n", bf->desc,
rsp->data[0] & bf->mask ? "en" : "dis");
}
@ -215,18 +201,26 @@ static int ipmi_bmc_get_enables(struct ipmi_intf * intf)
return 0;
}
static int ipmi_bmc_set_enables(struct ipmi_intf * intf, int argc, char ** argv)
/* ipmi_mc_set_enables - set MC enable flags
*
* @intf: ipmi inteface
* @argc: argument count
* @argv: argument list
*
* returns 0 on success
* returns -1 on error
*/
static int
ipmi_mc_set_enables(struct ipmi_intf * intf, int argc, char ** argv)
{
struct ipmi_rs * rsp;
struct ipmi_rq req;
struct bitfield_data * bf;
unsigned char en;
uint8_t en;
int i;
ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN);
if (argc < 1 || !strncmp(argv[0], "help", 4)) {
printf_bmc_usage();
if (argc < 1 || strncmp(argv[0], "help", 4) == 0) {
printf_mc_usage();
return 0;
}
@ -235,12 +229,12 @@ static int ipmi_bmc_set_enables(struct ipmi_intf * intf, int argc, char ** argv)
req.msg.cmd = BMC_GET_GLOBAL_ENABLES;
rsp = intf->sendrecv(intf, &req);
if (!rsp) {
printf("Error in BMC Get Global Enables Command\n");
if (rsp == NULL) {
lprintf(LOG_ERR, "Get Global Enables command failed");
return -1;
}
if (rsp->ccode) {
printf("BMC Get Global Enables command failed: %s\n",
if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Get Global Enables command failed: %s",
val2str(rsp->ccode, completion_code_vals));
return -1;
}
@ -248,27 +242,27 @@ static int ipmi_bmc_set_enables(struct ipmi_intf * intf, int argc, char ** argv)
en = rsp->data[0];
for (i = 0; i < argc; i++) {
for (bf = bmc_enables_bf; bf->name; bf++) {
for (bf = mc_enables_bf; bf->name != NULL; bf++) {
int nl = strlen(bf->name);
if (!strncmp(argv[i], bf->name, nl)) {
if (!strncmp(argv[i]+nl+1, "off", 3)) {
printf("Disabling %s\n", bf->desc);
en &= ~bf->mask;
}
else if (!strncmp(argv[i]+nl+1, "on", 2)) {
printf("Enabling %s\n", bf->desc);
en |= bf->mask;
}
else {
printf("Unrecognized option: %s\n", argv[i]);
}
if (strncmp(argv[i], bf->name, nl) != 0)
continue;
if (strncmp(argv[i]+nl+1, "off", 3) == 0) {
printf("Disabling %s\n", bf->desc);
en &= ~bf->mask;
}
else if (strncmp(argv[i]+nl+1, "on", 2) == 0) {
printf("Enabling %s\n", bf->desc);
en |= bf->mask;
}
else {
lprintf(LOG_ERR, "Unrecognized option: %s", argv[i]);
}
}
}
if (en == rsp->data[0]) {
printf("\nNothing to change...\n");
ipmi_bmc_get_enables(intf);
ipmi_mc_get_enables(intf);
return 0;
}
@ -277,15 +271,18 @@ static int ipmi_bmc_set_enables(struct ipmi_intf * intf, int argc, char ** argv)
req.msg.data_len = 1;
rsp = intf->sendrecv(intf, &req);
if (!rsp)
printf("Error in BMC Set Global Enables Command\n");
else if (rsp->ccode)
printf("BMC Set Global Enables command failed: %s\n",
val2str(rsp->ccode, completion_code_vals));
else {
printf("\nVerifying...\n");
ipmi_bmc_get_enables(intf);
if (rsp == NULL) {
lprintf(LOG_ERR, "Set Global Enables command failed");
return -1;
}
else if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Set Global Enables command failed: %s",
val2str(rsp->ccode, completion_code_vals));
return -1;
}
printf("\nVerifying...\n");
ipmi_mc_get_enables(intf);
return 0;
}
@ -302,7 +299,15 @@ const char *ipm_dev_adtl_dev_support[8] = {
"Chassis Device" /* bit 7 */
};
static int ipmi_bmc_get_deviceid(struct ipmi_intf * intf)
/* ipmi_mc_get_deviceid - print information about this MC
*
* @intf: ipmi interface
*
* returns 0 on success
* returns -1 on error
*/
static int
ipmi_mc_get_deviceid(struct ipmi_intf * intf)
{
struct ipmi_rs * rsp;
struct ipmi_rq req;
@ -315,12 +320,13 @@ static int ipmi_bmc_get_deviceid(struct ipmi_intf * intf)
req.msg.data_len = 0;
rsp = intf->sendrecv(intf, &req);
if (!rsp) {
printf("Error in BMC Get Device ID Command\n");
if (rsp == NULL) {
lprintf(LOG_ERR, "Get Device ID command failed");
return -1;
}
if (rsp->ccode) {
printf("BMC Get Device ID returned %x\n", rsp->ccode);
if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Get Device ID command failed: %s",
val2str(rsp->ccode, completion_code_vals));
return -1;
}
@ -338,7 +344,7 @@ static int ipmi_bmc_get_deviceid(struct ipmi_intf * intf)
printf("Manufacturer ID : %lu\n",
(long)IPM_DEV_MANUFACTURER_ID(devid->manufacturer_id));
printf("Product ID : %u (0x%02x%02x)\n",
buf2short((unsigned char *)(devid->product_id)),
buf2short((uint8_t *)(devid->product_id)),
devid->product_id[1], devid->product_id[0]);
printf("Device Available : %s\n",
(devid->fw_rev1 & IPM_DEV_FWREV1_AVAIL_MASK) ?
@ -362,34 +368,82 @@ static int ipmi_bmc_get_deviceid(struct ipmi_intf * intf)
return 0;
}
int ipmi_bmc_main(struct ipmi_intf * intf, int argc, char ** argv)
/* 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)
{
if (!argc || !strncmp(argv[0], "help", 4)) {
printf_bmc_usage();
return 0;
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;
}
else if (!strncmp(argv[0], "reset", 5)) {
if (argc < 2 || !strncmp(argv[1], "help", 4)) {
printf("reset commands: warm, cold\n");
}
else if (!strncmp(argv[1], "cold", 4)) {
ipmi_bmc_reset(intf, BMC_COLD_RESET);
}
else if (!strncmp(argv[1], "warm", 4)) {
ipmi_bmc_reset(intf, BMC_WARM_RESET);
}
else {
printf("reset commands: warm, cold\n");
}
}
else if (!strncmp(argv[0], "info", 4)) {
ipmi_bmc_get_deviceid(intf);
}
else if (!strncmp(argv[0], "getenables", 7)) {
ipmi_bmc_get_enables(intf);
}
else if (!strncmp(argv[0], "setenables", 7)) {
ipmi_bmc_set_enables(intf, argc-1, &(argv[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
*
* @intf: ipmi interface
* @argc: number of arguments
* @argv: argument list
*
* returns 0 on success
* returns -1 on error
*/
int
ipmi_mc_main(struct ipmi_intf * intf, int argc, char ** argv)
{
int rc = 0;
if (argc < 1 || strncmp(argv[0], "help", 4) == 0) {
printf_mc_usage();
}
else if (strncmp(argv[0], "reset", 5) == 0) {
if (argc < 2 || strncmp(argv[1], "help", 4) == 0) {
lprintf(LOG_ERR, "reset commands: warm, cold");
}
else if (strncmp(argv[1], "cold", 4) == 0) {
rc = ipmi_mc_reset(intf, BMC_COLD_RESET);
}
else if (strncmp(argv[1], "warm", 4) == 0) {
rc = ipmi_mc_reset(intf, BMC_WARM_RESET);
}
else {
lprintf(LOG_ERR, "reset commands: warm, cold");
}
}
else if (strncmp(argv[0], "info", 4) == 0) {
rc = ipmi_mc_get_deviceid(intf);
}
else if (strncmp(argv[0], "guid", 4) == 0) {
rc = ipmi_mc_get_guid(intf);
}
else if (strncmp(argv[0], "getenables", 10) == 0) {
rc = ipmi_mc_get_enables(intf);
}
else if (strncmp(argv[0], "setenables", 10) == 0) {
rc = ipmi_mc_set_enables(intf, argc-1, &(argv[1]));
}
return rc;
}

150
ipmitool/lib/ipmi_oem.c Normal file
View File

@ -0,0 +1,150 @@
/*
* 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 <string.h>
#include <ipmitool/ipmi.h>
#include <ipmitool/ipmi_intf.h>
#include <ipmitool/ipmi_constants.h>
#include <ipmitool/log.h>
#include <ipmitool/helper.h>
static int ipmi_oem_supermicro(struct ipmi_intf * intf);
static struct ipmi_oem_handle ipmi_oem_list[] = {
{
name: "supermicro",
desc: "Supermicro IPMIv1.5 BMC with OEM LAN authentication support",
setup: ipmi_oem_supermicro,
},
{
name: "intelwv2",
desc: "Intel SE7501WV2 IPMIv1.5 BMC with extra LAN communication support",
},
{
name: "intelplus",
desc: "Intel IPMI 2.0 BMC with RMCP+ communication support",
},
{ 0 },
};
/* Supermicro IPMIv2 BMCs use OEM authtype */
static int
ipmi_oem_supermicro(struct ipmi_intf * intf)
{
ipmi_intf_session_set_authtype(intf, IPMI_SESSION_AUTHTYPE_OEM);
return 0;
}
/* ipmi_oem_print - print list of OEM handles
*/
void
ipmi_oem_print(void)
{
struct ipmi_oem_handle * oem;
lprintf(LOG_NOTICE, "\nOEM Support:");
for (oem=ipmi_oem_list; oem->name != NULL && oem->desc != NULL; oem++) {
lprintf(LOG_NOTICE, "\t%-12s %s", oem->name, oem->desc);
}
lprintf(LOG_NOTICE, "");
}
/* ipmi_oem_setup - do initial setup of OEM handle
*
* @intf: ipmi interface
* @oemtype: OEM handle name
*
* returns 0 on success
* returns -1 on error
*/
int
ipmi_oem_setup(struct ipmi_intf * intf, char * oemtype)
{
struct ipmi_oem_handle * oem;
int i;
int rc = 0;
if (strncmp(oemtype, "help", 4) == 0 ||
strncmp(oemtype, "list", 4) == 0 ||
oemtype == NULL) {
ipmi_oem_print();
return -1;
}
for (oem=ipmi_oem_list, i=0; i < sizeof(ipmi_oem_list)/sizeof(struct ipmi_oem_handle); oem++, i++) {
if (oem->name == NULL)
continue;
if (strncmp(oemtype, oem->name, strlen(oem->name)) == 0)
break;
}
if (oem->name == NULL) {
/* nothing was found */
lprintf(LOG_ERR, "OEM support not found for \"%s\"", oemtype);
return -1;
}
/* save pointer for later use */
intf->oem = oem;
/* run optional setup function if it is defined */
if (oem->setup != NULL) {
lprintf(LOG_DEBUG, "Running OEM setup for \"%s\"", oem->desc);
rc = oem->setup(intf);
}
return rc;
}
/* ipmi_oem_active - used to determine if a particular OEM type is set
*
* @intf: ipmi interface
* @oemtype: string containing name of ipmi handle to check
*
* returns 1 if requested ipmi handle is active
* returns 0 otherwise
*/
int
ipmi_oem_active(struct ipmi_intf * intf, const char * oemtype)
{
if (intf->oem == NULL)
return 0;
if (strncmp(intf->oem->name, oemtype, strlen(oemtype)) == 0)
return 1;
return 0;
}

861
ipmitool/lib/ipmi_pef.c Normal file
View File

@ -0,0 +1,861 @@
/*
* Copyright (c) 2004 Dell Computers. 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 Dell Computers, 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.
* DELL COMPUTERS ("DELL") 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
* DELL 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 DELL 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 <string.h>
#include <math.h>
#include <time.h>
#include <ipmitool/helper.h>
#include <ipmitool/log.h>
#include <ipmitool/ipmi.h>
#include <ipmitool/ipmi_intf.h>
#include <ipmitool/ipmi_pef.h>
extern int verbose;
/*
// common kywd/value printf() templates
*/
static const char * pef_fld_fmts[][2] = {
{"%-*s : %u\n", " | %u"}, /* F_DEC: unsigned value */
{"%-*s : %d\n", " | %d"}, /* F_INT: signed value */
{"%-*s : %s\n", " | %s"}, /* F_STR: string value */
{"%-*s : 0x%x\n", " | 0x%x"}, /* F_HEX: "N hex digits" */
{"%-*s : 0x%04x\n", " | 0x%04x"}, /* F_2XD: "2 hex digits" */
{"%-*s : 0x%02x\n", " | 0x%02x"}, /* F_1XD: "1 hex digit" */
{"%-*s : %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
" | %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x"},
};
typedef enum {
F_DEC,
F_INT,
F_STR,
F_HEX,
F_2XD,
F_1XD,
F_UID,
} fmt_e;
#define KYWD_LENGTH 24
static int first_field = 1;
static const char * pef_flag_fmts[][3] = {
{"", "false", "true"},
{"supported", "un", ""},
{"active", "in", ""},
{"abled", "dis", "en"},
};
static const char * listitem[] = {" | %s", ",%s", "%s"};
const char *
ipmi_pef_bit_desc(struct bit_desc_map * map, uint32_t value)
{ /*
// return description/text label(s) for the given value.
// NB: uses a static buffer
*/
static char buf[128];
char * p;
struct desc_map * pmap;
uint32_t match, index;
*(p = buf) = '\0';
index = 2;
for (pmap=map->desc_maps; pmap && pmap->desc; pmap++) {
if (map->desc_map_type == BIT_DESC_MAP_LIST)
match = (value == pmap->mask);
else
match = ((value & pmap->mask) == pmap->mask);
if (match) {
sprintf(p, listitem[index], pmap->desc);
p = strchr(p, '\0');
if (map->desc_map_type != BIT_DESC_MAP_ALL)
break;
index = 1;
}
}
if (p == buf)
return("None");
return((const char *)buf);
}
void
ipmi_pef_print_flags(struct bit_desc_map * map, flg_e type, uint32_t val)
{ /*
// print features/flags, using val (a bitmask), according to map.
// observe the verbose flag, and print any labels, etc. based on type
*/
struct desc_map * pmap;
uint32_t maskval, index;
index = 0;
for (pmap=map->desc_maps; pmap && pmap->desc; pmap++) {
maskval = (val & pmap->mask);
if (verbose)
printf("%-*s : %s%s\n", KYWD_LENGTH,
ipmi_pef_bit_desc(map, pmap->mask),
pef_flag_fmts[type][1 + (maskval != 0)],
pef_flag_fmts[type][0]);
else if (maskval != 0) {
printf(listitem[index], ipmi_pef_bit_desc(map, maskval));
index = 1;
}
}
}
static void
ipmi_pef_print_field(const char * fmt[2], const char * label, unsigned long val)
{ /*
// print a 'field' (observes 'verbose' flag)
*/
if (verbose)
printf(fmt[0], KYWD_LENGTH, label, val);
else if (first_field)
printf(&fmt[1][2], val); /* skip field separator */
else
printf(fmt[1], val);
first_field = 0;
}
void
ipmi_pef_print_dec(const char * text, uint32_t val)
{ /* unsigned */
ipmi_pef_print_field(pef_fld_fmts[F_DEC], text, val);
}
void
ipmi_pef_print_int(const char * text, uint32_t val)
{ /* signed */
ipmi_pef_print_field(pef_fld_fmts[F_INT], text, val);
}
void
ipmi_pef_print_hex(const char * text, uint32_t val)
{ /* hex */
ipmi_pef_print_field(pef_fld_fmts[F_HEX], text, val);
}
void
ipmi_pef_print_str(const char * text, const char * val)
{ /* string */
ipmi_pef_print_field(pef_fld_fmts[F_STR], text, (unsigned long)val);
}
void
ipmi_pef_print_2xd(const char * text, uint8_t u1, uint8_t u2)
{ /* 2 hex digits */
uint32_t val = ((u1 << 8) + u2) & 0xffff;
ipmi_pef_print_field(pef_fld_fmts[F_2XD], text, val);
}
void
ipmi_pef_print_1xd(const char * text, uint32_t val)
{ /* 1 hex digit */
ipmi_pef_print_field(pef_fld_fmts[F_1XD], text, val);
}
static struct ipmi_rs *
ipmi_pef_msg_exchange(struct ipmi_intf * intf, struct ipmi_rq * req, char * txt)
{ /*
// common IPMItool rqst/resp handling
*/
struct ipmi_rs * rsp = intf->sendrecv(intf, req);
if (!rsp)
return(NULL);
if (rsp->ccode) {
lprintf(LOG_ERR, " **Error %x in '%s' command",
rsp ? rsp->ccode : 0, txt);
return(NULL);
}
if (verbose > 2)
printbuf(rsp->data, rsp->data_len, txt);
return(rsp);
}
static uint8_t
ipmi_pef_get_policy_table(struct ipmi_intf * intf,
struct pef_cfgparm_policy_table_entry ** table)
{ /*
// get the PEF policy table: allocate space, fillin, and return its size
// NB: the caller must free the returned area (when returned size > 0)
*/
struct ipmi_rs * rsp;
struct ipmi_rq req;
struct pef_cfgparm_selector psel;
struct pef_cfgparm_policy_table_entry * ptbl, * ptmp;
uint32_t i;
uint8_t tbl_size;
memset(&psel, 0, sizeof(psel));
psel.id = PEF_CFGPARM_ID_PEF_ALERT_POLICY_TABLE_SIZE;
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_SE;
req.msg.cmd = IPMI_CMD_GET_PEF_CONFIG_PARMS;
req.msg.data = (uint8_t *)&psel;
req.msg.data_len = sizeof(psel);
rsp = ipmi_pef_msg_exchange(intf, &req, "Alert policy table size");
if (!rsp)
return(0);
tbl_size = (rsp->data[1] & PEF_POLICY_TABLE_SIZE_MASK);
i = (tbl_size * sizeof(struct pef_cfgparm_policy_table_entry));
if (!i
|| (ptbl = (struct pef_cfgparm_policy_table_entry *)malloc(i)) == NULL)
return(0);
memset(&psel, 0, sizeof(psel));
psel.id = PEF_CFGPARM_ID_PEF_ALERT_POLICY_TABLE_ENTRY;
for (ptmp=ptbl, i=1; i<=tbl_size; i++) {
psel.set = (i & PEF_POLICY_TABLE_ID_MASK);
rsp = ipmi_pef_msg_exchange(intf, &req, "Alert policy table entry");
if (!rsp
|| i != (rsp->data[1] & PEF_POLICY_TABLE_ID_MASK)) {
lprintf(LOG_ERR, " **Error retrieving %s",
"Alert policy table entry");
free(ptbl);
ptbl = NULL;
tbl_size = 0;
break;
}
memcpy(ptmp, &rsp->data[1], sizeof(*ptmp));
ptmp++;
}
*table = ptbl;
return(tbl_size);
}
static void
ipmi_pef_print_lan_dest(struct ipmi_intf * intf, uint8_t ch, uint8_t dest)
{ /*
// print LAN alert destination info
*/
struct ipmi_rs * rsp;
struct ipmi_rq req;
struct pef_lan_cfgparm_selector lsel;
struct pef_lan_cfgparm_dest_type * ptype;
struct pef_lan_cfgparm_dest_info * pinfo;
char buf[32];
uint8_t tbl_size, dsttype, timeout, retries;
memset(&lsel, 0, sizeof(lsel));
lsel.id = PEF_LAN_CFGPARM_ID_DEST_COUNT;
lsel.ch = ch;
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_TRANSPORT;
req.msg.cmd = IPMI_CMD_LAN_GET_CONFIG;
req.msg.data = (uint8_t *)&lsel;
req.msg.data_len = sizeof(lsel);
rsp = ipmi_pef_msg_exchange(intf, &req, "Alert destination count");
if (!rsp) {
lprintf(LOG_ERR, " **Error retrieving %s",
"Alert destination count");
return;
}
tbl_size = (rsp->data[1] & PEF_LAN_DEST_TABLE_SIZE_MASK);
if (!dest || tbl_size == 0) /* LAN alerting not supported */
return;
lsel.id = PEF_LAN_CFGPARM_ID_DESTTYPE;
lsel.set = dest;
rsp = ipmi_pef_msg_exchange(intf, &req, "Alert destination type");
if (!rsp || rsp->data[1] != lsel.set) {
lprintf(LOG_ERR, " **Error retrieving %s",
"Alert destination type");
return;
}
ptype = (struct pef_lan_cfgparm_dest_type *)&rsp->data[1];
dsttype = (ptype->dest_type & PEF_LAN_DEST_TYPE_MASK);
timeout = ptype->alert_timeout;
retries = (ptype->retries & PEF_LAN_RETRIES_MASK);
ipmi_pef_print_str("Alert destination type",
ipmi_pef_bit_desc(&pef_b2s_lan_desttype, dsttype));
if (dsttype == PEF_LAN_DEST_TYPE_PET) {
lsel.id = PEF_LAN_CFGPARM_ID_PET_COMMUNITY;
lsel.set = 0;
rsp = ipmi_pef_msg_exchange(intf, &req, "PET community");
if (!rsp)
lprintf(LOG_ERR, " **Error retrieving %s",
"PET community");
else {
rsp->data[19] = '\0';
ipmi_pef_print_str("PET Community", &rsp->data[1]);
}
}
ipmi_pef_print_dec("ACK timeout/retry (secs)", timeout);
ipmi_pef_print_dec("Retries", retries);
lsel.id = PEF_LAN_CFGPARM_ID_DESTADDR;
lsel.set = dest;
rsp = ipmi_pef_msg_exchange(intf, &req, "Alert destination info");
if (!rsp || rsp->data[1] != lsel.set)
lprintf(LOG_ERR, " **Error retrieving %s",
"Alert destination info");
else {
pinfo = (struct pef_lan_cfgparm_dest_info *)&rsp->data[1];
sprintf(buf, "%u.%u.%u.%u",
pinfo->ip[0], pinfo->ip[1], pinfo->ip[2], pinfo->ip[3]);
ipmi_pef_print_str("IP address", buf);
sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x",
pinfo->mac[0], pinfo->mac[1], pinfo->mac[2],
pinfo->mac[3], pinfo->mac[4], pinfo->mac[5]);
ipmi_pef_print_str("MAC address", buf);
}
}
static void
ipmi_pef_print_serial_dest_dial(struct ipmi_intf * intf, char * label,
struct pef_serial_cfgparm_selector * ssel)
{ /*
// print a dial string
*/
#define BLOCK_SIZE 16
struct ipmi_rs * rsp;
struct ipmi_rq req;
struct pef_serial_cfgparm_selector tmp;
char * p, strval[(6 * BLOCK_SIZE) + 1];
memset(&tmp, 0, sizeof(tmp));
tmp.id = PEF_SERIAL_CFGPARM_ID_DEST_DIAL_STRING_COUNT;
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_TRANSPORT;
req.msg.cmd = IPMI_CMD_SERIAL_GET_CONFIG;
req.msg.data = (uint8_t *)&tmp;
req.msg.data_len = sizeof(tmp);
rsp = ipmi_pef_msg_exchange(intf, &req, "Dial string count");
if (!rsp || (rsp->data[1] & PEF_SERIAL_DIAL_STRING_COUNT_MASK) == 0)
return; /* sssh, not supported */
memcpy(&tmp, ssel, sizeof(tmp));
tmp.id = PEF_SERIAL_CFGPARM_ID_DEST_DIAL_STRING;
tmp.block = 1;
memset(strval, 0, sizeof(strval));
p = strval;
for (;;) {
rsp = ipmi_pef_msg_exchange(intf, &req, label);
if (!rsp
|| (rsp->data[1] != ssel->id)
|| (rsp->data[2] != tmp.block)) {
lprintf(LOG_ERR, " **Error retrieving %s", label);
return;
}
memcpy(p, &rsp->data[3], BLOCK_SIZE);
if (strchr(p, '\0') <= (p + BLOCK_SIZE))
break;
if ((p += BLOCK_SIZE) >= &strval[sizeof(strval)-1])
break;
tmp.block++;
}
ipmi_pef_print_str(label, strval);
#undef BLOCK_SIZE
}
static void
ipmi_pef_print_serial_dest_tap(struct ipmi_intf * intf,
struct pef_serial_cfgparm_selector * ssel)
{ /*
// print TAP destination info
*/
struct ipmi_rs * rsp;
struct ipmi_rq req;
struct pef_serial_cfgparm_selector tmp;
struct pef_serial_cfgparm_tap_svc_settings * pset;
uint8_t dialstr_id, setting_id;
memset(&tmp, 0, sizeof(tmp));
tmp.id = PEF_SERIAL_CFGPARM_ID_TAP_ACCT_COUNT;
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_TRANSPORT;
req.msg.cmd = IPMI_CMD_SERIAL_GET_CONFIG;
req.msg.data = (uint8_t *)&tmp;
req.msg.data_len = sizeof(tmp);
rsp = ipmi_pef_msg_exchange(intf, &req, "Number of TAP accounts");
if (!rsp || (rsp->data[1] & PEF_SERIAL_TAP_ACCT_COUNT_MASK) == 0)
return; /* sssh, not supported */
memcpy(&tmp, ssel, sizeof(tmp));
tmp.id = PEF_SERIAL_CFGPARM_ID_TAP_ACCT_INFO;
rsp = ipmi_pef_msg_exchange(intf, &req, "TAP account info");
if (!rsp || (rsp->data[1] != tmp.set)) {
lprintf(LOG_ERR, " **Error retrieving %s",
"TAP account info");
return;
}
dialstr_id = (rsp->data[2] & PEF_SERIAL_TAP_ACCT_INFO_DIAL_STRING_ID_MASK);
dialstr_id >>= PEF_SERIAL_TAP_ACCT_INFO_DIAL_STRING_ID_SHIFT;
setting_id = (rsp->data[2] & PEF_SERIAL_TAP_ACCT_INFO_SVC_SETTINGS_ID_MASK);
tmp.set = dialstr_id;
ipmi_pef_print_serial_dest_dial(intf, "TAP Dial string", &tmp);
tmp.set = setting_id;
rsp = ipmi_pef_msg_exchange(intf, &req, "TAP service settings");
if (!rsp || (rsp->data[1] != tmp.set)) {
lprintf(LOG_ERR, " **Error retrieving %s",
"TAP service settings");
return;
}
pset = (struct pef_serial_cfgparm_tap_svc_settings *)&rsp->data[1];
ipmi_pef_print_str("TAP confirmation",
ipmi_pef_bit_desc(&pef_b2s_tap_svc_confirm, pset->confirmation_flags));
/* TODO : additional TAP settings? */
}
static void
ipmi_pef_print_serial_dest_ppp(struct ipmi_intf * intf,
struct pef_serial_cfgparm_selector * ssel)
{ /*
// print PPP destination info
*/
/* TODO */
}
static void
ipmi_pef_print_serial_dest_callback(struct ipmi_intf * intf,
struct pef_serial_cfgparm_selector * ssel)
{ /*
// print callback destination info
*/
/* TODO */
}
static void
ipmi_pef_print_serial_dest(struct ipmi_intf * intf, uint8_t ch, uint8_t dest)
{ /*
// print Serial/PPP alert destination info
*/
struct ipmi_rs * rsp;
struct ipmi_rq req;
struct pef_serial_cfgparm_selector ssel;
uint8_t tbl_size, wrk;
struct pef_serial_cfgparm_dest_info * pinfo;
memset(&ssel, 0, sizeof(ssel));
ssel.id = PEF_SERIAL_CFGPARM_ID_DEST_COUNT;
ssel.ch = ch;
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_TRANSPORT;
req.msg.cmd = IPMI_CMD_SERIAL_GET_CONFIG;
req.msg.data = (uint8_t *)&ssel;
req.msg.data_len = sizeof(ssel);
rsp = ipmi_pef_msg_exchange(intf, &req, "Alert destination count");
if (!rsp) {
lprintf(LOG_ERR, " **Error retrieving %s",
"Alert destination count");
return;
}
tbl_size = (rsp->data[1] & PEF_SERIAL_DEST_TABLE_SIZE_MASK);
if (!dest || tbl_size == 0) /* Page alerting not supported */
return;
ssel.id = PEF_SERIAL_CFGPARM_ID_DESTINFO;
ssel.set = dest;
rsp = ipmi_pef_msg_exchange(intf, &req, "Alert destination info");
if (!rsp || rsp->data[1] != ssel.set)
lprintf(LOG_ERR, " **Error retrieving %s",
"Alert destination info");
else {
pinfo = (struct pef_serial_cfgparm_dest_info *)rsp->data;
wrk = (pinfo->dest_type & PEF_SERIAL_DEST_TYPE_MASK);
ipmi_pef_print_str("Alert destination type",
ipmi_pef_bit_desc(&pef_b2s_serial_desttype, wrk));
ipmi_pef_print_dec("ACK timeout (secs)",
pinfo->alert_timeout);
ipmi_pef_print_dec("Retries",
(pinfo->retries & PEF_SERIAL_RETRIES_MASK));
switch (wrk) {
case PEF_SERIAL_DEST_TYPE_DIAL:
ipmi_pef_print_serial_dest_dial(intf, "Serial dial string", &ssel);
break;
case PEF_SERIAL_DEST_TYPE_TAP:
ipmi_pef_print_serial_dest_tap(intf, &ssel);
break;
case PEF_SERIAL_DEST_TYPE_PPP:
ipmi_pef_print_serial_dest_ppp(intf, &ssel);
break;
case PEF_SERIAL_DEST_TYPE_BASIC_CALLBACK:
case PEF_SERIAL_DEST_TYPE_PPP_CALLBACK:
ipmi_pef_print_serial_dest_callback(intf, &ssel);
break;
}
}
}
static void
ipmi_pef_print_dest(struct ipmi_intf * intf, uint8_t ch, uint8_t dest)
{ /*
// print generic alert destination info
*/
ipmi_pef_print_dec("Destination ID", dest);
}
void
ipmi_pef_print_event_info(struct pef_cfgparm_filter_table_entry * pef, char * buf)
{ /*
// print PEF entry Event info: class, severity, trigger, etc.
*/
static char * classes[] = {"Discrete", "Threshold", "OEM"};
uint16_t offmask;
char * p;
int i;
uint8_t t;
ipmi_pef_print_str("Event severity",
ipmi_pef_bit_desc(&pef_b2s_severities, pef->entry.severity));
t = pef->entry.event_trigger;
if (t == PEF_EVENT_TRIGGER_THRESHOLD)
i = 1;
else if (t > PEF_EVENT_TRIGGER_SENSOR_SPECIFIC)
i = 2;
else
i = 0;
ipmi_pef_print_str("Event class", classes[i]);
offmask = ((pef->entry.event_data_1_offset_mask[1] << 8)
+ pef->entry.event_data_1_offset_mask[0]);
if (offmask == 0xffff || t == PEF_EVENT_TRIGGER_MATCH_ANY)
strcpy(buf, "Any");
else if (t == PEF_EVENT_TRIGGER_UNSPECIFIED)
strcpy(buf, "Unspecified");
else if (t == PEF_EVENT_TRIGGER_SENSOR_SPECIFIC)
strcpy(buf, "Sensor-specific");
else if (t > PEF_EVENT_TRIGGER_SENSOR_SPECIFIC)
strcpy(buf, "OEM");
else {
sprintf(buf, "(0x%02x/0x%04x)", t, offmask);
p = strchr(buf, '\0');
for (i=0; i<PEF_B2S_GENERIC_ER_ENTRIES; i++) {
if (offmask & 1) {
sprintf(p, ",%s", ipmi_pef_bit_desc(pef_b2s_generic_ER[t-1], i));
p = strchr(p, '\0');
}
offmask >>= 1;
}
}
ipmi_pef_print_str("Event trigger(s)", buf);
}
static void
ipmi_pef_print_entry(struct ipmi_rs * rsp, uint8_t id,
struct pef_cfgparm_filter_table_entry * pef)
{ /*
// print a PEF table entry
*/
uint8_t wrk, set;
char buf[128];
ipmi_pef_print_dec("PEF table entry", id);
wrk = !!(pef->entry.config & PEF_CONFIG_ENABLED);
sprintf(buf, "%sactive", (wrk ? "" : "in"));
if (pef->entry.config & PEF_CONFIG_PRECONFIGURED)
strcat(buf, ", pre-configured");
ipmi_pef_print_str("Status", buf);
if (wrk != 0) {
ipmi_pef_print_1xd("Version", rsp->data[0]);
ipmi_pef_print_str("Sensor type",
ipmi_pef_bit_desc(&pef_b2s_sensortypes, pef->entry.sensor_type));
if (pef->entry.sensor_number == PEF_SENSOR_NUMBER_MATCH_ANY)
ipmi_pef_print_str("Sensor number", "Any");
else
ipmi_pef_print_dec("Sensor number", pef->entry.sensor_number);
ipmi_pef_print_event_info(pef, buf);
ipmi_pef_print_str("Action",
ipmi_pef_bit_desc(&pef_b2s_actions, pef->entry.action));
if (pef->entry.action & PEF_ACTION_ALERT) {
set = (pef->entry.policy_number & PEF_POLICY_NUMBER_MASK);
ipmi_pef_print_int("Policy set", set);
}
}
}
static void
ipmi_pef_list_entries(struct ipmi_intf * intf)
{ /*
// list all PEF table entries
*/
struct ipmi_rs * rsp;
struct ipmi_rq req;
struct pef_cfgparm_selector psel;
struct pef_cfgparm_filter_table_entry * pcfg;
uint32_t i;
uint8_t max_filters;
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_SE;
req.msg.cmd = IPMI_CMD_GET_PEF_CAPABILITIES;
rsp = ipmi_pef_msg_exchange(intf, &req, "PEF capabilities");
if (!rsp
|| (max_filters = ((struct pef_capabilities *)rsp->data)->tblsize) == 0)
return; /* sssh, not supported */
memset(&psel, 0, sizeof(psel));
psel.id = PEF_CFGPARM_ID_PEF_FILTER_TABLE_ENTRY;
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_SE;
req.msg.cmd = IPMI_CMD_GET_PEF_CONFIG_PARMS;
req.msg.data = (uint8_t *)&psel;
req.msg.data_len = sizeof(psel);
for (i=1; i<=max_filters; i++) {
if (i > 1)
printf("\n");
psel.set = (i & PEF_FILTER_TABLE_ID_MASK);
rsp = ipmi_pef_msg_exchange(intf, &req, "PEF table entry");
if (!rsp
|| (psel.set != (rsp->data[1] & PEF_FILTER_TABLE_ID_MASK))) {
lprintf(LOG_ERR, " **Error retrieving %s",
"PEF table entry");
continue;
}
pcfg = (struct pef_cfgparm_filter_table_entry *)&rsp->data[1];
first_field = 1;
ipmi_pef_print_entry(rsp, psel.set, pcfg);
}
}
static void
ipmi_pef_list_policies(struct ipmi_intf * intf)
{ /*
// list PEF alert policies
*/
struct ipmi_rs * rsp;
struct ipmi_rq req;
struct pef_cfgparm_policy_table_entry * ptbl, * ptmp;
uint32_t i;
uint8_t wrk, ch, medium, tbl_size;
tbl_size = ipmi_pef_get_policy_table(intf, &ptbl);
if (!tbl_size)
return;
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_APP;
req.msg.cmd = IPMI_CMD_GET_CHANNEL_INFO;
req.msg.data = &ch;
req.msg.data_len = sizeof(ch);
for (ptmp=ptbl, i=1; i<=tbl_size; i++, ptmp++) {
if ((ptmp->entry.policy & PEF_POLICY_ENABLED) == PEF_POLICY_ENABLED) {
if (i > 1)
printf("\n");
first_field = 1;
ipmi_pef_print_dec("Alert policy table entry",
(ptmp->data1 & PEF_POLICY_TABLE_ID_MASK));
ipmi_pef_print_dec("Policy set",
(ptmp->entry.policy & PEF_POLICY_ID_MASK) >> PEF_POLICY_ID_SHIFT);
ipmi_pef_print_str("Policy entry rule",
ipmi_pef_bit_desc(&pef_b2s_policies, (ptmp->entry.policy & PEF_POLICY_FLAGS_MASK)));
if (ptmp->entry.alert_string_key & PEF_POLICY_EVENT_SPECIFIC) {
ipmi_pef_print_str("Event-specific", "true");
continue;
}
wrk = ptmp->entry.chan_dest;
/* channel/description */
ch = (wrk & PEF_POLICY_CHANNEL_MASK) >> PEF_POLICY_CHANNEL_SHIFT;
rsp = ipmi_pef_msg_exchange(intf, &req, "Channel info");
if (!rsp || rsp->data[0] != ch) {
lprintf(LOG_ERR, " **Error retrieving %s",
"Channel info");
continue;
}
medium = rsp->data[1];
ipmi_pef_print_dec("Channel number", ch);
ipmi_pef_print_str("Channel medium",
ipmi_pef_bit_desc(&pef_b2s_ch_medium, medium));
/* destination/description */
wrk &= PEF_POLICY_DESTINATION_MASK;
switch (medium) {
case PEF_CH_MEDIUM_TYPE_LAN:
ipmi_pef_print_lan_dest(intf, ch, wrk);
break;
case PEF_CH_MEDIUM_TYPE_SERIAL:
ipmi_pef_print_serial_dest(intf, ch, wrk);
break;
default:
ipmi_pef_print_dest(intf, ch, wrk);
break;
}
}
}
free(ptbl);
}
static void
ipmi_pef_get_status(struct ipmi_intf * intf)
{ /*
// report the PEF status
*/
struct ipmi_rs * rsp;
struct ipmi_rq req;
struct pef_cfgparm_selector psel;
char tbuf[40];
time_t ts;
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_SE;
req.msg.cmd = IPMI_CMD_GET_LAST_PROCESSED_EVT_ID;
rsp = ipmi_pef_msg_exchange(intf, &req, "Last S/W processed ID");
if (!rsp) {
lprintf(LOG_ERR, " **Error retrieving %s",
"Last S/W processed ID");
return;
}
#if WORDS_BIGENDIAN
ts = (time_t)(rsp->data[0]<<24 + rsp->data[1]<<16 + rsp->data[2]<<8 + rsp->data[3]);
#else
ts = (time_t)(*(long *)rsp->data);
#endif
strftime(tbuf, sizeof(tbuf), "%m/%d/%Y %H:%M:%S", localtime(&ts));
ipmi_pef_print_str("Last SEL addition", tbuf);
ipmi_pef_print_2xd("Last SEL record ID", rsp->data[5], rsp->data[4]);
ipmi_pef_print_2xd("Last S/W processed ID", rsp->data[7], rsp->data[6]);
ipmi_pef_print_2xd("Last BMC processed ID", rsp->data[9], rsp->data[8]);
memset(&psel, 0, sizeof(psel));
psel.id = PEF_CFGPARM_ID_PEF_CONTROL;
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_SE;
req.msg.cmd = IPMI_CMD_GET_PEF_CONFIG_PARMS;
req.msg.data = (uint8_t *)&psel;
req.msg.data_len = sizeof(psel);
rsp = ipmi_pef_msg_exchange(intf, &req, "PEF control");
if (!rsp) {
lprintf(LOG_ERR, " **Error retrieving %s",
"PEF control");
return;
}
ipmi_pef_print_flags(&pef_b2s_control, P_ABLE, rsp->data[1]);
}
static void
ipmi_pef_get_info(struct ipmi_intf * intf)
{ /*
// report PEF capabilities + System GUID
*/
struct ipmi_rs * rsp;
struct ipmi_rq req;
struct pef_capabilities * pcap;
struct pef_cfgparm_selector psel;
struct pef_cfgparm_policy_table_entry * ptbl;
uint8_t * uid;
uint8_t actions, tbl_size;
if ((tbl_size = ipmi_pef_get_policy_table(intf, &ptbl)) > 0)
free(ptbl);
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_SE;
req.msg.cmd = IPMI_CMD_GET_PEF_CAPABILITIES;
rsp = ipmi_pef_msg_exchange(intf, &req, "PEF capabilities");
if (!rsp)
return;
pcap = (struct pef_capabilities *)rsp->data;
ipmi_pef_print_1xd("Version", pcap->version);
ipmi_pef_print_dec("PEF table size", pcap->tblsize);
ipmi_pef_print_dec("Alert policy table size", tbl_size);
actions = pcap->actions;
memset(&psel, 0, sizeof(psel));
psel.id = PEF_CFGPARM_ID_SYSTEM_GUID;
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_SE;
req.msg.cmd = IPMI_CMD_GET_PEF_CONFIG_PARMS;
req.msg.data = (uint8_t *)&psel;
req.msg.data_len = sizeof(psel);
rsp = ipmi_pef_msg_exchange(intf, &req, "System GUID");
uid = NULL;
if (rsp && (rsp->data[1] & PEF_SYSTEM_GUID_USED_IN_PET))
uid = &rsp->data[2];
else {
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_APP;
req.msg.cmd = IPMI_CMD_GET_SYSTEM_GUID;
rsp = ipmi_pef_msg_exchange(intf, &req, "System GUID");
if (rsp)
uid = &rsp->data[0];
}
if (uid) { /* got GUID? */
if (verbose)
printf(pef_fld_fmts[F_UID][0], KYWD_LENGTH, "System GUID",
uid[0], uid[1], uid[2], uid[3], uid[4], uid[5], uid[6], uid[7],
uid[8], uid[9], uid[10],uid[11],uid[12],uid[13],uid[14],uid[15]);
else
printf(pef_fld_fmts[F_UID][1],
uid[0], uid[1], uid[2], uid[3], uid[4], uid[5], uid[6], uid[7],
uid[8], uid[9], uid[10],uid[11],uid[12],uid[13],uid[14],uid[15]);
}
ipmi_pef_print_flags(&pef_b2s_actions, P_SUPP, actions);
}
int ipmi_pef_main(struct ipmi_intf * intf, int argc, char ** argv)
{ /*
// PEF subcommand handling
*/
int help = 0;
if (!argc || !strncmp(argv[0], "info", 4))
ipmi_pef_get_info(intf);
else if (!strncmp(argv[0], "help", 4))
help = 1;
else if (!strncmp(argv[0], "status", 6))
ipmi_pef_get_status(intf);
else if (!strncmp(argv[0], "policy", 6))
ipmi_pef_list_policies(intf);
else if (!strncmp(argv[0], "list", 4))
ipmi_pef_list_entries(intf);
else {
help = 1;
lprintf(LOG_ERR, "Invalid PEF command: '%s'\n", argv[0]);
}
if (help)
lprintf(LOG_NOTICE, "PEF commands: info status policy list");
else if (!verbose)
printf("\n");
return 0;
}

View File

@ -39,24 +39,33 @@
#include <stdio.h>
#include <ipmitool/ipmi.h>
#include <ipmitool/log.h>
#include <ipmitool/helper.h>
#include <ipmitool/ipmi_intf.h>
#include <ipmitool/ipmi_raw.h>
int ipmi_raw_main(struct ipmi_intf * intf, int argc, char ** argv)
int
ipmi_raw_main(struct ipmi_intf * intf, int argc, char ** argv)
{
struct ipmi_rs * rsp;
struct ipmi_rq req;
unsigned char netfn, cmd;
uint8_t netfn, cmd;
int i;
unsigned char data[32];
if (argc < 2 || !strncmp(argv[0], "help", 4)) {
printf("RAW Commands: raw <netfn> <cmd> [data]\n");
uint8_t data[256];
if (argc < 2 || strncmp(argv[0], "help", 4) == 0) {
lprintf(LOG_NOTICE, "RAW Commands: raw <netfn> <cmd> [data]");
return -1;
}
else if (argc > sizeof(data))
{
lprintf(LOG_NOTICE, "Raw command input limit (256 bytes) exceeded");
return -1;
}
netfn = (unsigned char)strtol(argv[0], NULL, 0);
cmd = (unsigned char)strtol(argv[1], NULL, 0);
netfn = (uint8_t)strtol(argv[0], NULL, 0);
cmd = (uint8_t)strtol(argv[1], NULL, 0);
memset(data, 0, sizeof(data));
memset(&req, 0, sizeof(req));
@ -65,34 +74,35 @@ int ipmi_raw_main(struct ipmi_intf * intf, int argc, char ** argv)
req.msg.data = data;
for (i=2; i<argc; i++) {
unsigned char val = (unsigned char)strtol(argv[i], NULL, 0);
uint8_t val = (uint8_t)strtol(argv[i], NULL, 0);
req.msg.data[i-2] = val;
req.msg.data_len++;
}
if (verbose && req.msg.data_len) {
for (i=0; i<req.msg.data_len; i++) {
if (((i%16) == 0) && (i != 0))
printf("\n");
printf(" %2.2x", req.msg.data[i]);
}
printf("\n");
}
if (verbose)
printf("RAW REQ (netfn=0x%x cmd=0x%x data_len=%d)\n",
req.msg.netfn, req.msg.cmd, req.msg.data_len);
lprintf(LOG_INFO, "RAW REQ (netfn=0x%x cmd=0x%x data_len=%d)",
req.msg.netfn, req.msg.cmd, req.msg.data_len);
printbuf(req.msg.data, req.msg.data_len, "RAW REQUEST");
rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode) {
printf("Error:%x sending RAW command\n",
rsp ? rsp->ccode : 0);
if (rsp == NULL) {
lprintf(LOG_ERR, "Unable to send RAW command "
"(netfn=0x%x cmd=0x%x)",
req.msg.netfn, req.msg.cmd);
return -1;
}
if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Unable to send RAW command "
"(netfn=0x%x cmd=0x%x rsp=0x%x): %s",
req.msg.netfn, req.msg.cmd, rsp->ccode,
val2str(rsp->ccode, completion_code_vals));
return -1;
}
if (verbose)
printf("RAW RSP (%d bytes)\n", rsp->data_len);
lprintf(LOG_INFO, "RAW RSP (%d bytes)", rsp->data_len);
/* print the raw response buffer */
for (i=0; i<rsp->data_len; i++) {
if (((i%16) == 0) && (i != 0))
printf("\n");

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -37,17 +37,18 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <ipmitool/ipmi.h>
#include <ipmitool/ipmi_intf.h>
#include <ipmitool/helper.h>
#include <ipmitool/log.h>
#include <ipmitool/ipmi_lanp.h>
#include <ipmitool/ipmi_session.h>
#include <ipmitool/ipmi_strings.h>
@ -96,11 +97,19 @@ print_session_info_csv(const struct get_session_info_rsp * session_info,
if (data_len == 18)
{
/* We have 802.3 LAN data */
#ifdef __CYGWIN__
printf(",%d.%d.%d.%d",
session_info->channel_data.lan_data.console_ip[0],
session_info->channel_data.lan_data.console_ip[1],
session_info->channel_data.lan_data.console_ip[2],
session_info->channel_data.lan_data.console_ip[3]);
#else
printf(",%s",
inet_ntop(AF_INET,
&(session_info->channel_data.lan_data.console_ip),
buffer,
16));
#endif
printf(",%02x:%02x:%02x:%02x:%02x:%02x",
session_info->channel_data.lan_data.console_mac[0],
@ -128,11 +137,19 @@ print_session_info_csv(const struct get_session_info_rsp * session_info,
printf(",%d",
session_info->channel_data.modem_data.destination_selector);
#ifdef __CYGWIN__
printf(",%d.%d.%d.%d",
session_info->channel_data.modem_data.console_ip[0],
session_info->channel_data.modem_data.console_ip[1],
session_info->channel_data.modem_data.console_ip[2],
session_info->channel_data.modem_data.console_ip[3]);
#else
printf(",%s",
inet_ntop(AF_INET,
&(session_info->channel_data.modem_data.console_ip),
buffer,
16));
#endif
if (data_len == 14)
{
@ -184,11 +201,19 @@ print_session_info_verbose(const struct get_session_info_rsp * session_info,
if (data_len == 18)
{
/* We have 802.3 LAN data */
#ifdef __CYGWIN__
printf("console ip : %d.%d.%d.%d\n",
session_info->channel_data.lan_data.console_ip[0],
session_info->channel_data.lan_data.console_ip[1],
session_info->channel_data.lan_data.console_ip[2],
session_info->channel_data.lan_data.console_ip[3]);
#else
printf("console ip : %s\n",
inet_ntop(AF_INET,
&(session_info->channel_data.lan_data.console_ip),
buffer,
16));
#endif
printf("console mac : %02x:%02x:%02x:%02x:%02x:%02x\n",
session_info->channel_data.lan_data.console_mac[0],
@ -216,11 +241,19 @@ print_session_info_verbose(const struct get_session_info_rsp * session_info,
printf("Destination selector : %d\n",
session_info->channel_data.modem_data.destination_selector);
#ifdef __CYGWIN__
printf("console ip : %d.%d.%d.%d\n",
session_info->channel_data.modem_data.console_ip[0],
session_info->channel_data.modem_data.console_ip[1],
session_info->channel_data.modem_data.console_ip[2],
session_info->channel_data.modem_data.console_ip[3]);
#else
printf("console ip : %s\n",
inet_ntop(AF_INET,
&(session_info->channel_data.modem_data.console_ip),
buffer,
16));
#endif
if (data_len == 14)
{
@ -262,7 +295,7 @@ ipmi_get_session_info(struct ipmi_intf * intf,
struct ipmi_rs * rsp;
struct ipmi_rq req;
unsigned char rqdata[5]; // max length of the variable length request
uint8_t rqdata[5]; // max length of the variable length request
struct get_session_info_rsp session_info;
memset(&req, 0, sizeof(req));
@ -293,24 +326,33 @@ ipmi_get_session_info(struct ipmi_intf * intf,
break;
case IPMI_SESSION_REQUEST_BY_HANDLE:
rqdata[0] = 0xFE;
rqdata[1] = (unsigned char)id_or_handle;
rqdata[1] = (uint8_t)id_or_handle;
req.msg.data_len = 2;
break;
case IPMI_SESSION_REQUEST_ALL:
break;
}
rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode) {
printf("Error:%x Get Session Info Command\n", rsp ? rsp->ccode : 0);
if ((session_request_type == IPMI_SESSION_REQUEST_CURRENT) &&
(strncmp(intf->name, "intf_lan", 8)))
printf("It is likely that the channel in use does not support sessions\n");
if (rsp == NULL)
{
lprintf(LOG_ERR, "Get Session Info command failed");
retval = -1;
}
else if (rsp->ccode > 0)
{
lprintf(LOG_ERR, "Get Session Info command failed: %s",
val2str(rsp->ccode, completion_code_vals));
retval = -1;
}
if (retval < 0)
{
if ((session_request_type == IPMI_SESSION_REQUEST_CURRENT) &&
(strncmp(intf->name, "lan", 3) != 0))
lprintf(LOG_ERR, "It is likely that the channel in use "
"does not support sessions");
}
else
{
memcpy(&session_info, rsp->data, rsp->data_len);
@ -326,20 +368,27 @@ ipmi_get_session_info(struct ipmi_intf * intf,
rqdata[0] = i++;
rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode || (rsp->data_len < 3))
if (rsp == NULL)
{
if (!rsp || (rsp->ccode != 0xCC))
{
printf("Error:%x Get Session Info Command\n", rsp ? rsp->ccode : 0);
retval = -1;
}
lprintf(LOG_ERR, "Get Session Info command failed");
retval = -1;
break;
}
else
else if (rsp->ccode > 0 && rsp->ccode != 0xCC && rsp->ccode != 0xCB)
{
memcpy(&session_info, rsp->data, rsp->data_len);
print_session_info(&session_info, rsp->data_len);
lprintf(LOG_ERR, "Get Session Info command failed: %s",
val2str(rsp->ccode, completion_code_vals));
retval = -1;
break;
}
else if (rsp->data_len < 3)
{
retval = -1;
break;
}
memcpy(&session_info, rsp->data, rsp->data_len);
print_session_info(&session_info, rsp->data_len);
} while (i <= session_info.session_slot_count);
break;
@ -353,7 +402,7 @@ ipmi_get_session_info(struct ipmi_intf * intf,
void
printf_session_usage()
{
printf("Session Commands: info <active | all | id 0xnnnnnnnn | handle 0xnn>\n");
lprintf(LOG_NOTICE, "Session Commands: info <active | all | id 0xnnnnnnnn | handle 0xnn>");
}
@ -362,31 +411,27 @@ ipmi_session_main(struct ipmi_intf * intf, int argc, char ** argv)
{
int retval = 0;
if (!argc || !strncmp(argv[0], "help", 4))
if (argc == 0 || strncmp(argv[0], "help", 4) == 0)
{
printf_session_usage();
retval = 1;
}
else if (!strncmp(argv[0], "info", 4))
else if (strncmp(argv[0], "info", 4) == 0)
{
if ((argc < 2) || !strncmp(argv[1], "help", 4))
if ((argc < 2) || strncmp(argv[1], "help", 4) == 0)
{
printf_session_usage();
retval = 1;
}
else
{
Ipmi_Session_Request_Type session_request_type = 0;
uint32_t id_or_handle = 0;
if (!strncmp(argv[1], "active", 6))
if (strncmp(argv[1], "active", 6) == 0)
session_request_type = IPMI_SESSION_REQUEST_CURRENT;
else if (!strncmp(argv[1], "all", 3))
else if (strncmp(argv[1], "all", 3) == 0)
session_request_type = IPMI_SESSION_REQUEST_ALL;
else if (!strncmp(argv[1], "id", 2))
else if (strncmp(argv[1], "id", 2) == 0)
{
if (argc >= 3)
{
@ -395,12 +440,12 @@ ipmi_session_main(struct ipmi_intf * intf, int argc, char ** argv)
}
else
{
printf("Missing id argument\n");
lprintf(LOG_ERR, "Missing id argument");
printf_session_usage();
retval = 1;
retval = -1;
}
}
else if (!strncmp(argv[1], "handle", 6))
else if (strncmp(argv[1], "handle", 6) == 0)
{
if (argc >= 3)
{
@ -409,20 +454,20 @@ ipmi_session_main(struct ipmi_intf * intf, int argc, char ** argv)
}
else
{
printf("Missing handle argument\n");
lprintf(LOG_ERR, "Missing handle argument");
printf_session_usage();
retval = 1;
retval = -1;
}
}
else
{
printf("Invalid SESSION info parameter: %s\n", argv[1]);
lprintf(LOG_ERR, "Invalid SESSION info parameter: %s", argv[1]);
printf_session_usage();
retval = 1;
retval = -1;
}
if (! retval)
if (retval == 0)
retval = ipmi_get_session_info(intf,
session_request_type,
id_or_handle);
@ -430,9 +475,9 @@ ipmi_session_main(struct ipmi_intf * intf, int argc, char ** argv)
}
else
{
printf("Invalid SESSION command: %s\n", argv[0]);
lprintf(LOG_ERR, "Invalid SESSION command: %s", argv[0]);
printf_session_usage();
retval = 1;
retval = -1;
}
return retval;

File diff suppressed because it is too large Load Diff

View File

@ -37,15 +37,7 @@
#include <stddef.h>
#include <ipmitool/ipmi_strings.h>
#include <ipmitool/ipmi_constants.h>
const struct valstr ipmi_channel_activity_type_vals[] = {
{ 0, "IPMI Messaging session active" },
{ 1, "Callback Messaging session active" },
{ 2, "Dial-out Alert active" },
{ 3, "TAP Page Active" },
{ 0x00, NULL },
};
#include <ipmitool/ipmi_sensor.h>
/*
@ -61,6 +53,14 @@ const struct valstr impi_bit_rate_vals[] = {
{ 0x00, NULL },
};
const struct valstr ipmi_channel_activity_type_vals[] = {
{ 0, "IPMI Messaging session active" },
{ 1, "Callback Messaging session active" },
{ 2, "Dial-out Alert active" },
{ 3, "TAP Page Active" },
{ 0x00, NULL },
};
const struct valstr ipmi_privlvl_vals[] = {
{ IPMI_SESSION_PRIV_CALLBACK, "CALLBACK" },
@ -99,3 +99,180 @@ const struct valstr ipmi_authtype_vals[] = {
{ IPMI_1_5_AUTH_TYPE_BIT_OEM, "OEM" },
{ 0, NULL },
};
const struct valstr entity_id_vals[] = {
{ 0x00, "Unspecified" },
{ 0x01, "Other" },
{ 0x02, "Unknown" },
{ 0x03, "Processor" },
{ 0x04, "Disk or Disk Bay" },
{ 0x05, "Peripheral Bay" },
{ 0x06, "System Management Module" },
{ 0x07, "System Board" },
{ 0x08, "Memory Module" },
{ 0x09, "Processor Module" },
{ 0x0a, "Power Supply" },
{ 0x0b, "Add-in Card" },
{ 0x0c, "Front Panel Board" },
{ 0x0d, "Back Panel Board" },
{ 0x0e, "Power System Board" },
{ 0x0f, "Drive Backplane" },
{ 0x10, "System Internal Expansion Board" },
{ 0x11, "Other System Board" },
{ 0x12, "Processor Board" },
{ 0x13, "Power Unit" },
{ 0x14, "Power Module" },
{ 0x15, "Power Management" },
{ 0x16, "Chassis Back Panel Board" },
{ 0x17, "System Chassis" },
{ 0x18, "Sub-Chassis" },
{ 0x19, "Other Chassis Board" },
{ 0x1a, "Disk Drive Bay" },
{ 0x1b, "Peripheral Bay" },
{ 0x1c, "Device Bay" },
{ 0x1d, "Fan Device" },
{ 0x1e, "Cooling Unit" },
{ 0x1f, "Cable/Interconnect" },
{ 0x20, "Memory Device" },
{ 0x21, "System Management Software" },
{ 0x22, "BIOS" },
{ 0x23, "Operating System" },
{ 0x24, "System Bus" },
{ 0x25, "Group" },
{ 0x26, "Remote Management Device" },
{ 0x27, "External Environment" },
{ 0x28, "Battery" },
{ 0x00, NULL },
};
const struct valstr entity_device_type_vals[] = {
{ 0x00, "Reserved" },
{ 0x01, "Reserved" },
{ 0x02, "DS1624 temperature sensor" },
{ 0x03, "DS1621 temperature sensor" },
{ 0x04, "LM75 Temperature Sensor" },
{ 0x05, "Heceta ASIC" },
{ 0x06, "Reserved" },
{ 0x07, "Reserved" },
{ 0x08, "EEPROM, 24C01" },
{ 0x09, "EEPROM, 24C02" },
{ 0x0a, "EEPROM, 24C04" },
{ 0x0b, "EEPROM, 24C08" },
{ 0x0c, "EEPROM, 24C16" },
{ 0x0d, "EEPROM, 24C17" },
{ 0x0e, "EEPROM, 24C32" },
{ 0x0f, "EEPROM, 24C64" },
{ 0x1000, "IPMI FRU Inventory" },
{ 0x1001, "DIMM Memory ID" },
{ 0x1002, "IPMI FRU Inventory" },
{ 0x1003, "System Processor Cartridge FRU" },
{ 0x11, "Reserved" },
{ 0x12, "Reserved" },
{ 0x13, "Reserved" },
{ 0x14, "PCF 8570 256 byte RAM" },
{ 0x15, "PCF 8573 clock/calendar" },
{ 0x16, "PCF 8574A I/O Port" },
{ 0x17, "PCF 8583 clock/calendar" },
{ 0x18, "PCF 8593 clock/calendar" },
{ 0x19, "Clock calendar" },
{ 0x1a, "PCF 8591 A/D, D/A Converter" },
{ 0x1b, "I/O Port" },
{ 0x1c, "A/D Converter" },
{ 0x1d, "D/A Converter" },
{ 0x1e, "A/D, D/A Converter" },
{ 0x1f, "LCD Controller/Driver" },
{ 0x20, "Core Logic (Chip set) Device" },
{ 0x21, "LMC6874 Intelligent Battery controller" },
{ 0x22, "Intelligent Batter controller" },
{ 0x23, "Combo Management ASIC" },
{ 0x24, "Maxim 1617 Temperature Sensor" },
{ 0xbf, "Other/Unspecified" },
{ 0x00, NULL },
};
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 },
};
const struct valstr ipmi_channel_medium_vals[] = {
{ IPMI_CHANNEL_MEDIUM_RESERVED, "reserved" },
{ IPMI_CHANNEL_MEDIUM_IPMB, "IPMB (I2C)" },
{ IPMI_CHANNEL_MEDIUM_ICMB_1, "ICMB v1.0" },
{ IPMI_CHANNEL_MEDIUM_ICMB_09, "ICMB v0.9" },
{ IPMI_CHANNEL_MEDIUM_LAN, "802.3 LAN" },
{ IPMI_CHANNEL_MEDIUM_SERIAL, "Serial/Modem" },
{ IPMI_CHANNEL_MEDIUM_LAN_OTHER,"Other LAN" },
{ IPMI_CHANNEL_MEDIUM_SMBUS_PCI,"PCI SMBus" },
{ IPMI_CHANNEL_MEDIUM_SMBUS_1, "SMBus v1.0/v1.1" },
{ IPMI_CHANNEL_MEDIUM_SMBUS_2, "SMBus v2.0" },
{ IPMI_CHANNEL_MEDIUM_USB_1, "USB 1.x" },
{ IPMI_CHANNEL_MEDIUM_USB_2, "USB 2.x" },
{ IPMI_CHANNEL_MEDIUM_SYSTEM, "System Interface" },
{ 0x00, NULL },
};
const struct valstr completion_code_vals[] = {
{ 0x00, "Command completed normally" },
{ 0xc0, "Node busy" },
{ 0xc1, "Invalid command" },
{ 0xc2, "Invalid command on LUN" },
{ 0xc3, "Timeout" },
{ 0xc4, "Out of space" },
{ 0xc5, "Reservation cancelled or invalid" },
{ 0xc6, "Request data truncated" },
{ 0xc7, "Request data length invalid" },
{ 0xc8, "Request data field length limit exceeded" },
{ 0xc9, "Parameter out of range" },
{ 0xca, "Cannot return number of requested data bytes" },
{ 0xcb, "Requested sensor, data, or record not found" },
{ 0xcc, "Invalid data field in request" },
{ 0xcd, "Command illegal for specified sensor or record type" },
{ 0xce, "Command response could not be provided" },
{ 0xcf, "Cannot execute duplicated request" },
{ 0xd0, "SDR Repository in update mode" },
{ 0xd1, "Device firmeware in update mode" },
{ 0xd2, "BMC initialization in progress" },
{ 0xd3, "Destination unavailable" },
{ 0xd4, "Insufficient privilege level" },
{ 0xd5, "Command not supported in present state" },
{ 0xff, "Unspecified error" },
{ 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

@ -37,13 +37,14 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <signal.h>
#include <unistd.h>
#include <ipmitool/helper.h>
#include <ipmitool/log.h>
#include <ipmitool/ipmi.h>
#include <ipmitool/ipmi_intf.h>
#include <ipmitool/ipmi_user.h>
@ -65,29 +66,29 @@ extern int csv_output;
/*
* ipmi_get_user_access
*
* param intf [in]
* param intf [in]
* param channel_number [in]
* param user_id [in]
* param user_access [out]
* param user_id [in]
* param user_access [out]
*
* return 0 on succes
* 1 on failure
* 1 on failure
*/
static int
ipmi_get_user_access(
struct ipmi_intf * intf,
unsigned char channel_number,
unsigned char user_id,
struct user_access_rsp * user_access)
struct ipmi_intf * intf,
uint8_t channel_number,
uint8_t user_id,
struct user_access_rsp * user_access)
{
struct ipmi_rs * rsp;
struct ipmi_rq req;
unsigned char msg_data[2];
struct ipmi_rs * rsp;
struct ipmi_rq req;
uint8_t msg_data[2];
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_APP; /* 0x06 */
req.msg.cmd = IPMI_GET_USER_ACCESS; /* 0x44 */
req.msg.netfn = IPMI_NETFN_APP; /* 0x06 */
req.msg.cmd = IPMI_GET_USER_ACCESS; /* 0x44 */
req.msg.data = msg_data;
req.msg.data_len = 2;
@ -98,16 +99,21 @@ ipmi_get_user_access(
rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode)
{
printf("Error:%x Get User Access Command (user 0x%x)\n",
rsp ? rsp->ccode : 0, msg_data[1]);
if (rsp == NULL) {
lprintf(LOG_ERR, "Get User Access command failed "
"(channel %d, user %d)", channel_number, user_id);
return -1;
}
if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Get User Access command failed "
"(channel %d, user %d): %s", channel_number, user_id,
val2str(rsp->ccode, completion_code_vals));
return -1;
}
memcpy(user_access,
rsp->data,
sizeof(struct user_access_rsp));
rsp->data,
sizeof(struct user_access_rsp));
return 0;
}
@ -117,28 +123,28 @@ ipmi_get_user_access(
/*
* ipmi_get_user_name
*
* param intf [in]
* param intf [in]
* param channel_number [in]
* param user_id [in]
* param user_name [out]
* param user_id [in]
* param user_name [out]
*
* return 0 on succes
* 1 on failure
* 1 on failure
*/
static int
ipmi_get_user_name(
struct ipmi_intf * intf,
unsigned char user_id,
char * user_name)
struct ipmi_intf * intf,
uint8_t user_id,
char * user_name)
{
struct ipmi_rs * rsp;
struct ipmi_rq req;
unsigned char msg_data[1];
struct ipmi_rs * rsp;
struct ipmi_rq req;
uint8_t msg_data[1];
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_APP; /* 0x06 */
req.msg.cmd = IPMI_GET_USER_NAME; /* 0x45 */
req.msg.netfn = IPMI_NETFN_APP; /* 0x06 */
req.msg.cmd = IPMI_GET_USER_NAME; /* 0x45 */
req.msg.data = msg_data;
req.msg.data_len = 1;
@ -146,10 +152,14 @@ ipmi_get_user_name(
rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode)
{
printf("Error:%x Get User Name Command (user 0x%x)\n",
rsp ? rsp->ccode : 0, msg_data[0]);
if (rsp == NULL) {
lprintf(LOG_ERR, "Get User Name command failed (user %d)",
user_id);
return -1;
}
if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Get User Name command failed (user %d): %s",
user_id, val2str(rsp->ccode, completion_code_vals));
return -1;
}
@ -163,91 +173,94 @@ ipmi_get_user_name(
static void
dump_user_access(
unsigned char user_id,
const char * user_name,
struct user_access_rsp * user_access)
uint8_t user_id,
const char * user_name,
struct user_access_rsp * user_access)
{
static int printed_header = 0;
if (! printed_header)
{
printf("ID Name Callin Link Auth IPMI Msg "
"Channel Priv Limit\n");
printf("ID Name Callin Link Auth IPMI Msg "
"Channel Priv Limit\n");
printed_header = 1;
}
printf("%-4d%-17s%-8s%-11s%-11s%-s\n",
user_id,
user_name,
user_access->no_callin_access? "false": "true ",
user_access->link_auth_access? "true ": "false",
user_access->ipmi_messaging_access? "true ": "false",
val2str(user_access->channel_privilege_limit,
ipmi_privlvl_vals));
user_id,
user_name,
user_access->no_callin_access? "false": "true ",
user_access->link_auth_access? "true ": "false",
user_access->ipmi_messaging_access? "true ": "false",
val2str(user_access->channel_privilege_limit,
ipmi_privlvl_vals));
}
static void
dump_user_access_csv(
unsigned char user_id,
const char * user_name,
struct user_access_rsp * user_access)
uint8_t user_id,
const char * user_name,
struct user_access_rsp * user_access)
{
printf("%d,%s,%s,%s,%s,%s\n",
user_id,
user_name,
user_access->no_callin_access? "false": "true",
user_access->link_auth_access? "true": "false",
user_access->ipmi_messaging_access? "true": "false",
val2str(user_access->channel_privilege_limit,
ipmi_privlvl_vals));
user_id,
user_name,
user_access->no_callin_access? "false": "true",
user_access->link_auth_access? "true": "false",
user_access->ipmi_messaging_access? "true": "false",
val2str(user_access->channel_privilege_limit,
ipmi_privlvl_vals));
}
static int
ipmi_print_user_list(
struct ipmi_intf * intf,
unsigned char channel_number)
struct ipmi_intf * intf,
uint8_t channel_number)
{
/* This is where you were! */
char user_name[17];
struct user_access_rsp user_access;
unsigned char current_user_id = 1;
uint8_t current_user_id = 1;
do
{
if (ipmi_get_user_access(intf,
channel_number,
current_user_id,
&user_access))
channel_number,
current_user_id,
&user_access))
return -1;
if (ipmi_get_user_name(intf,
current_user_id,
user_name))
current_user_id,
user_name))
return -1;
if ((current_user_id == 0) ||
user_access.link_auth_access ||
user_access.ipmi_messaging_access ||
strcmp("", user_name))
if ((current_user_id == 0) ||
user_access.link_auth_access ||
user_access.ipmi_messaging_access ||
strcmp("", user_name))
{
if (csv_output)
dump_user_access_csv(current_user_id, user_name, &user_access);
dump_user_access_csv(current_user_id,
user_name, &user_access);
else
dump_user_access(current_user_id, user_name, &user_access);
dump_user_access(current_user_id,
user_name,
&user_access);
}
++current_user_id;
} while((current_user_id < user_access.maximum_ids) &&
(current_user_id < 63)); /* Absolute maximum allowed by spec */
} while((current_user_id <= user_access.maximum_ids) &&
(current_user_id <= 63)); /* Absolute maximum allowed by spec */
return 0;
@ -257,32 +270,32 @@ ipmi_print_user_list(
static int
ipmi_print_user_summary(
struct ipmi_intf * intf,
unsigned char channel_number)
struct ipmi_intf * intf,
uint8_t channel_number)
{
struct user_access_rsp user_access;
if (ipmi_get_user_access(intf,
channel_number,
1,
&user_access))
channel_number,
1,
&user_access))
return -1;
if (csv_output)
{
printf("%d,%d,%d\n",
user_access.maximum_ids,
user_access.enabled_user_count,
user_access.fixed_name_count);
user_access.maximum_ids,
user_access.enabled_user_count,
user_access.fixed_name_count);
}
else
{
printf("Maximum IDs : %d\n",
user_access.maximum_ids);
printf("Maximum IDs : %d\n",
user_access.maximum_ids);
printf("Enabled User Count : %d\n",
user_access.enabled_user_count);
user_access.enabled_user_count);
printf("Fixed Name Count : %d\n",
user_access.fixed_name_count);
user_access.fixed_name_count);
}
return 0;
@ -295,17 +308,17 @@ ipmi_print_user_summary(
*/
static int
ipmi_user_set_username(
struct ipmi_intf * intf,
unsigned char user_id,
const char * name)
struct ipmi_intf * intf,
uint8_t user_id,
const char * name)
{
struct ipmi_rs * rsp;
struct ipmi_rq req;
unsigned char msg_data[17];
struct ipmi_rs * rsp;
struct ipmi_rq req;
uint8_t msg_data[17];
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_APP; /* 0x06 */
req.msg.cmd = IPMI_SET_USER_NAME; /* 0x45 */
req.msg.netfn = IPMI_NETFN_APP; /* 0x06 */
req.msg.cmd = IPMI_SET_USER_NAME; /* 0x45 */
req.msg.data = msg_data;
req.msg.data_len = 17;
@ -317,13 +330,16 @@ ipmi_user_set_username(
rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode)
{
printf("Error:%x Set User Name Command\n",
rsp ? rsp->ccode : 0);
if (rsp == NULL) {
lprintf(LOG_ERR, "Set User Name command failed (user %d, name %s)",
user_id, name);
return -1;
}
if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Set User Name command failed (user %d, name %s): %s",
user_id, name, val2str(rsp->ccode, completion_code_vals));
return -1;
}
return 0;
}
@ -339,83 +355,120 @@ ipmi_user_set_username(
*/
static int
ipmi_user_set_password(
struct ipmi_intf * intf,
unsigned char user_id,
unsigned char operation,
const char * password)
struct ipmi_intf * intf,
uint8_t user_id,
uint8_t operation,
const char * password,
int is_twenty_byte_password)
{
struct ipmi_rs * rsp;
struct ipmi_rq req;
unsigned char msg_data[18];
struct ipmi_rs * rsp;
struct ipmi_rq req;
char * msg_data;
int password_length = (is_twenty_byte_password? 20 : 16);
msg_data = (char*)malloc(password_length + 2);
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_APP; /* 0x06 */
req.msg.cmd = IPMI_SET_USER_PASSWORD; /* 0x47 */
req.msg.netfn = IPMI_NETFN_APP; /* 0x06 */
req.msg.cmd = IPMI_SET_USER_PASSWORD; /* 0x47 */
req.msg.data = msg_data;
req.msg.data_len = 18;
req.msg.data_len = password_length + 2;
/* The channel number will remain constant throughout this function */
msg_data[0] = user_id;
if (is_twenty_byte_password)
msg_data[0] |= 0x80;
msg_data[1] = operation;
memset(msg_data + 2, 0, 16);
memset(msg_data + 2, 0, password_length);
if (password)
strcpy(msg_data + 2, password);
if (password != NULL)
strncpy(msg_data + 2, password, password_length);
rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode)
{
printf("Error:%x Set User Password Command\n",
rsp ? rsp->ccode : 0);
if (rsp == NULL) {
lprintf(LOG_ERR, "Set User Password command failed (user %d)",
user_id);
return -1;
}
if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Set User Password command failed (user %d): %s",
user_id, val2str(rsp->ccode, completion_code_vals));
return rsp->ccode;
}
return 0;
}
/*
* ipmi_user_test_password
*
* Call ipmi_user_set_password, and interpret the result
*/
static int
ipmi_user_test_password(
struct ipmi_intf * intf,
uint8_t user_id,
const char * password,
int is_twenty_byte_password)
{
int ret;
ret = ipmi_user_set_password(intf,
user_id,
IPMI_PASSWORD_TEST_PASSWORD,
password,
is_twenty_byte_password);
switch (ret) {
case 0:
printf("Success\n");
break;
case 0x80:
printf("Failure: password incorrect\n");
break;
case 0x81:
printf("Failure: wrong password size\n");
break;
default:
printf("Unknown error\n");
}
return ((ret == 0) ? 0 : -1);
}
/*
* print_user_usage
*/
void
print_user_usage()
{
printf("\n");
printf("User Commands: summary [<channel number>]\n");
printf(" list [<channel number>]\n");
printf(" set name <user id> <username>\n");
printf(" set password <user id> [<password>]\n");
printf(" disable <user id> [<channel number>]\n");
printf(" enable <user id> [<channel number>]\n");
printf("\n");
}
/*
*
*/
void
print_user_set_usage()
{
printf("\nUser set parameters and values: \n\n");
printf(" name <character string (max 16 chars)>\n");
printf(" password <password string (max 16 chars)>\n");
printf("\n");
lprintf(LOG_NOTICE, "User Commands: summary [<channel number>]");
lprintf(LOG_NOTICE, " list [<channel number>]");
lprintf(LOG_NOTICE, " set name <user id> <username>");
lprintf(LOG_NOTICE, " set password <user id> [<password>]");
lprintf(LOG_NOTICE, " disable <user id>");
lprintf(LOG_NOTICE, " enable <user id>");
lprintf(LOG_NOTICE, " test <user id> <16|20> [<password]>\n");
}
const char *
ipmi_user_build_password_prompt(unsigned char user_id)
ipmi_user_build_password_prompt(uint8_t user_id)
{
static char prompt[128];
sprintf(prompt, "Password for user %d: ", user_id);
memset(prompt, 0, 128);
snprintf(prompt, 128, "Password for user %d: ", user_id);
return prompt;
}
@ -431,24 +484,25 @@ ipmi_user_main(struct ipmi_intf * intf, int argc, char ** argv)
{
int retval = 0;
ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN);
/*
* Help
*/
if (!argc || !strncmp(argv[0], "help", 4))
if (argc == 0 || strncmp(argv[0], "help", 4) == 0)
{
print_user_usage();
}
/*
* Summary
*/
else if (!strncmp(argv[0], "summary", 7)) {
unsigned char channel;
else if (strncmp(argv[0], "summary", 7) == 0)
{
uint8_t channel;
if (argc == 1)
channel = 0x0E; /* Ask about the current channel */
else if (argc == 2)
channel = (unsigned char)strtol(argv[1], NULL, 0);
channel = (uint8_t)strtol(argv[1], NULL, 0);
else
{
print_user_usage();
@ -462,13 +516,14 @@ ipmi_user_main(struct ipmi_intf * intf, int argc, char ** argv)
/*
* List
*/
else if (!strncmp(argv[0], "list", 4)) {
unsigned char channel;
else if (strncmp(argv[0], "list", 4) == 0)
{
uint8_t channel;
if (argc == 1)
channel = 0x0E; /* Ask about the current channel */
else if (argc == 2)
channel = (unsigned char)strtol(argv[1], NULL, 0);
channel = (uint8_t)strtol(argv[1], NULL, 0);
else
{
print_user_usage();
@ -478,25 +533,87 @@ ipmi_user_main(struct ipmi_intf * intf, int argc, char ** argv)
retval = ipmi_print_user_list(intf, channel);
}
/*
* Test
*/
else if (strncmp(argv[0], "test", 4) == 0)
{
// a little fucking irritating, isn't it
if ((argc == 3 || argc == 4) &&
((strncmp(argv[2], "16", 2) == 0) ||
(strncmp(argv[2], "20", 2) == 0)))
{
char * password = NULL;
int password_length = atoi(argv[2]);
uint8_t user_id = (uint8_t)strtol(argv[1],
NULL,
0);
if (user_id == 0)
{
lprintf(LOG_ERR, "Invalid user ID: %d", user_id);
return -1;
}
if (argc == 3)
{
/* We need to prompt for a password */
char * tmp;
const char * password_prompt =
ipmi_user_build_password_prompt(user_id);
#ifdef HAVE_GETPASSPHRASE
tmp = getpassphrase (password_prompt);
#else
tmp = (char*)getpass (password_prompt);
#endif
if (tmp != NULL)
password = strdup(tmp);
if (password == NULL) {
lprintf(LOG_ERR, "ipmitool: malloc failure");
return -1;
}
}
else
password = argv[3];
retval = ipmi_user_test_password(intf,
user_id,
password,
password_length == 20);
}
else
{
print_user_usage();
return -1;
}
}
/*
* Set
*/
else if (!strncmp(argv[0], "set", 3))
else if (strncmp(argv[0], "set", 3) == 0)
{
/*
* Set Password
*/
if ((argc >= 3) &&
(! strcmp("password", argv[1])))
if ((argc >= 3) &&
(strncmp("password", argv[1], 8) == 0))
{
char * password = NULL;
unsigned char user_id = (unsigned char)strtol(argv[2],
NULL,
0);
if (! user_id)
uint8_t user_id = (uint8_t)strtol(argv[2],
NULL,
0);
if (user_id == 0)
{
printf("Error. Invalid user ID: %d\n", user_id);
lprintf(LOG_ERR, "Invalid user ID: %d", user_id);
return -1;
}
@ -510,33 +627,53 @@ ipmi_user_main(struct ipmi_intf * intf, int argc, char ** argv)
ipmi_user_build_password_prompt(user_id);
#ifdef HAVE_GETPASSPHRASE
if ((tmp = getpassphrase (password_prompt)))
tmp = getpassphrase (password_prompt);
#else
if ((tmp = (char*)getpass (password_prompt)))
tmp = (char*)getpass (password_prompt);
#endif
if (tmp != NULL)
{
password = strdup(tmp);
if (password == NULL) {
lprintf(LOG_ERR, "ipmitool: malloc failure");
return -1;
}
#ifdef HAVE_GETPASSPHRASE
if ((tmp = getpassphrase (password_prompt)))
tmp = getpassphrase (password_prompt);
#else
if ((tmp = (char*)getpass (password_prompt)))
tmp = (char*)getpass (password_prompt);
#endif
if (tmp != NULL)
{
if (strcmp(password, tmp))
if (strlen(password) != strlen(tmp))
{
printf("Error. Passwords to not match.\n");
lprintf(LOG_ERR, "Passwords do not match");
return -1;
}
if (strncmp(password, tmp, strlen(tmp)))
{
lprintf(LOG_ERR, "Passwords to not match");
return -1;
}
}
}
}
else
password = argv[3];
if (strlen(password) > 20)
{
lprintf(LOG_ERR, "Password is too long (> 20 bytes)");
return -1;
}
retval = ipmi_user_set_password(intf,
user_id,
IPMI_PASSWORD_SET_PASSWORD,
argc == 4? argv[3]: password);
user_id,
IPMI_PASSWORD_SET_PASSWORD,
password,
strlen(password) > 16);
}
@ -544,23 +681,23 @@ ipmi_user_main(struct ipmi_intf * intf, int argc, char ** argv)
* Set Name
*/
else if ((argc >= 2) &&
(! strcmp("name", argv[1])))
(strncmp("name", argv[1], 4) == 0))
{
if (argc != 4)
{
print_user_set_usage();
print_user_usage();
return -1;
}
retval = ipmi_user_set_username(intf,
(unsigned char)strtol(argv[2],
NULL,
0),
argv[3]);
(uint8_t)strtol(argv[2],
NULL,
0),
argv[3]);
}
else
{
print_user_set_usage();
print_user_usage();
return -1;
}
}
@ -569,11 +706,11 @@ ipmi_user_main(struct ipmi_intf * intf, int argc, char ** argv)
/*
* Disable / Enable
*/
else if ((!strncmp(argv[0], "disable", 7)) ||
(!strncmp(argv[0], "enable", 6)))
else if ((strncmp(argv[0], "disable", 7) == 0) ||
(strncmp(argv[0], "enable", 6) == 0))
{
unsigned char user_id;
unsigned char operation;
uint8_t user_id;
uint8_t operation;
char null_password[16]; /* Not used, but required */
memset(null_password, 0, sizeof(null_password));
@ -584,30 +721,31 @@ ipmi_user_main(struct ipmi_intf * intf, int argc, char ** argv)
return -1;
}
user_id = (unsigned char)strtol(argv[1],
NULL,
0);
if (! user_id)
user_id = (uint8_t)strtol(argv[1],
NULL,
0);
if (user_id == 0)
{
printf("Error. Invalid user ID: %d\n", user_id);
lprintf(LOG_ERR, "Invalid user ID: %d", user_id);
return -1;
}
operation = (!strncmp(argv[0], "disable", 7))?
IPMI_PASSWORD_DISABLE_USER: IPMI_PASSWORD_ENABLE_USER;
operation = (strncmp(argv[0], "disable", 7) == 0) ?
IPMI_PASSWORD_DISABLE_USER : IPMI_PASSWORD_ENABLE_USER;
retval = ipmi_user_set_password(intf,
user_id,
operation,
null_password);
user_id,
operation,
null_password,
0); /* This field is ignored */
}
else
{
print_user_usage();
retval = -1;
}
return retval;

View File

@ -74,7 +74,7 @@ void lprintf(int level, const char * format, ...)
if (logpriv->daemon)
syslog(level, "%s", logmsg);
else
printf("%s\n", logmsg);
fprintf(stderr, "%s\n", logmsg);
return;
}
@ -116,6 +116,9 @@ void log_init(const char * name, int isdaemon, int verbose)
logpriv->name = strdup(name);
else
logpriv->name = strdup(LOG_NAME_DEFAULT);
if (logpriv->name == NULL)
fprintf(stderr, "ipmitool: malloc failure\n");
logpriv->daemon = isdaemon;
logpriv->level = verbose + LOG_NOTICE;
@ -140,6 +143,7 @@ void log_halt(void)
closelog();
free(logpriv);
logpriv = NULL;
}
int log_level_get(void)

View File

@ -46,6 +46,11 @@
#include <sys/stat.h>
#include <sys/poll.h>
#ifdef __FreeBSD__
#include <signal.h>
#include <paths.h>
#endif
#include <config.h>
#ifdef HAVE_OPENIPMI_H
@ -79,21 +84,21 @@ static void daemonize(void)
#ifdef SIGHUP
sigemptyset(&sighup);
sigaddset(&sighup, SIGHUP);
if (sigprocmask(SIG_UNBLOCK, &sighup, nil) < 0)
if (sigprocmask(SIG_UNBLOCK, &sighup, NULL) < 0)
fprintf(stderr, "ERROR: could not unblock SIGHUP signal\n");
SIG_IGNORE(SIGHUP);
signal(SIGHUP, SIG_IGN);
#endif
#ifdef SIGTTOU
SIG_IGNORE(SIGTTOU);
signal(SIGTTOU, SIG_IGN);
#endif
#ifdef SIGTTIN
SIG_IGNORE(SIGTTIN);
signal(SIGTTIN, SIG_IGN);
#endif
#ifdef SIGQUIT
SIG_IGNORE(SIGQUIT);
signal(SIGQUIT, SIG_IGN);
#endif
#ifdef SIGTSTP
SIG_IGNORE(SIGTSTP);
signal(SIGTSTP, SIG_IGN);
#endif
pid = (pid_t) fork();
@ -130,7 +135,7 @@ static int enable_event_msg_buffer(struct ipmi_intf * intf)
{
struct ipmi_rs * rsp;
struct ipmi_rq req;
unsigned char bmc_global_enables;
uint8_t bmc_global_enables;
/* we must read/modify/write bmc global enables */
memset(&req, 0, sizeof(req));
@ -187,7 +192,7 @@ static void read_event(struct ipmi_intf * intf)
{
struct ipmi_addr addr;
struct ipmi_recv recv;
unsigned char data[80];
uint8_t data[80];
int rv;
recv.addr = (char *) &addr;

View File

@ -42,6 +42,7 @@
#include <ctype.h>
#include <ipmitool/helper.h>
#include <ipmitool/log.h>
#include <ipmitool/ipmi.h>
#include <ipmitool/ipmi_intf.h>
#include <ipmitool/ipmi_session.h>
@ -77,11 +78,16 @@ static int rl_event_keepalive(void)
{
static int internal_timer = 0;
if (!shell_intf)
if (shell_intf == NULL)
return -1;
if (!shell_intf->keepalive)
if (shell_intf->keepalive == NULL)
return 0;
#if defined (RL_READLINE_VERSION) && RL_READLINE_VERSION >= 0x0402
if (internal_timer++ < RL_TIMEOUT)
#else
/* In readline < 4.2 keyboard timeout hardcoded to 0.1 second */
if (internal_timer++ < RL_TIMEOUT * 10)
#endif
return 0;
internal_timer = 0;
@ -106,8 +112,10 @@ int ipmi_shell_main(struct ipmi_intf * intf, int argc, char ** argv)
/* hook to keep lan sessions active */
shell_intf = intf;
rl_event_hook = rl_event_keepalive;
#if defined(RL_READLINE_VERSION) && RL_READLINE_VERSION >= 0x0402
/* set to 1 second */
rl_set_keyboard_input_timeout(1000*1000);
#endif
}
while ((pbuf = (char *)readline(RL_PROMPT)) != NULL) {
@ -115,11 +123,13 @@ int ipmi_shell_main(struct ipmi_intf * intf, int argc, char ** argv)
free(pbuf);
continue;
}
if (!strncmp(pbuf, "quit", 4) || !strncmp(pbuf, "exit", 4)) {
if (strncmp(pbuf, "quit", 4) == 0 ||
strncmp(pbuf, "exit", 4) == 0) {
free(pbuf);
return 0;
}
if (!strncmp(pbuf, "help", 4) || !strncmp(pbuf, "?", 1)) {
if (strncmp(pbuf, "help", 4) == 0 ||
strncmp(pbuf, "?", 1) == 0) {
ipmi_cmd_print();
free(pbuf);
continue;
@ -131,7 +141,9 @@ int ipmi_shell_main(struct ipmi_intf * intf, int argc, char ** argv)
__argc = 0;
ap = __argv;
for (*ap = strtok(pbuf, " \t"); *ap != NULL; *ap = strtok(NULL, " \t")) {
for (*ap = strtok(pbuf, " \t");
*ap != NULL;
*ap = strtok(NULL, " \t")) {
__argc++;
if (**ap != '\0') {
if (++ap >= &__argv[20])
@ -140,7 +152,10 @@ int ipmi_shell_main(struct ipmi_intf * intf, int argc, char ** argv)
}
if (__argc && __argv[0])
rc = ipmi_cmd_run(intf, __argv[0], __argc-1, &(__argv[1]));
rc = ipmi_cmd_run(intf,
__argv[0],
__argc-1,
&(__argv[1]));
free(pbuf);
}
@ -149,44 +164,46 @@ int ipmi_shell_main(struct ipmi_intf * intf, int argc, char ** argv)
#else /* HAVE_READLINE */
int ipmi_shell_main(struct ipmi_intf * intf, int argc, char ** argv)
int
ipmi_shell_main(struct ipmi_intf * intf, int argc, char ** argv)
{
printf("Compiled without readline support, shell is disabled.\n");
lprintf(LOG_ERR, "Compiled without readline, shell is disabled");
return -1;
}
#endif /* HAVE_READLINE */
static void ipmi_set_usage(void)
static void
ipmi_set_usage(void)
{
printf("Usage: set <option> <value>\n\n");
printf("Options are:\n");
printf(" hostname <host> Session hostname\n");
printf(" username <user> Session username\n");
printf(" password <pass> Session password\n");
printf(" privlvl <level> Session privilege level force\n");
printf(" authtype <type> Authentication type force\n");
printf(" localaddr <addr> Local IPMB address\n");
printf(" targetaddr <addr> Remote target IPMB address\n");
printf(" port <port> Remote RMCP port\n");
printf(" csv [level] enable output in comma separated format\n");
printf(" verbose [level] Verbose level\n");
printf("\n");
lprintf(LOG_NOTICE, "Usage: set <option> <value>\n");
lprintf(LOG_NOTICE, "Options are:");
lprintf(LOG_NOTICE, " hostname <host> Session hostname");
lprintf(LOG_NOTICE, " username <user> Session username");
lprintf(LOG_NOTICE, " password <pass> Session password");
lprintf(LOG_NOTICE, " privlvl <level> Session privilege level force");
lprintf(LOG_NOTICE, " authtype <type> Authentication type force");
lprintf(LOG_NOTICE, " localaddr <addr> Local IPMB address");
lprintf(LOG_NOTICE, " targetaddr <addr> Remote target IPMB address");
lprintf(LOG_NOTICE, " port <port> Remote RMCP port");
lprintf(LOG_NOTICE, " csv [level] enable output in comma separated format");
lprintf(LOG_NOTICE, " verbose [level] Verbose level");
lprintf(LOG_NOTICE, "");
}
int ipmi_set_main(struct ipmi_intf * intf, int argc, char ** argv)
{
if (!argc || !strncmp(argv[0], "help", 4)) {
if (argc == 0 || strncmp(argv[0], "help", 4) == 0) {
ipmi_set_usage();
return -1;
}
/* these options can have no arguments */
if (!strncmp(argv[0], "verbose", 7)) {
if (strncmp(argv[0], "verbose", 7) == 0) {
verbose = (argc > 1) ? atoi(argv[1]) : verbose+1;
return 0;
}
if (!strncmp(argv[0], "csv", 3)) {
if (strncmp(argv[0], "csv", 3) == 0) {
csv_output = (argc > 1) ? atoi(argv[1]) : 1;
return 0;
}
@ -197,43 +214,54 @@ int ipmi_set_main(struct ipmi_intf * intf, int argc, char ** argv)
return -1;
}
if (!strncmp(argv[0], "host", 4) || !strncmp(argv[0], "hostname", 8)) {
if (strncmp(argv[0], "host", 4) == 0 ||
strncmp(argv[0], "hostname", 8) == 0) {
ipmi_intf_session_set_hostname(intf, argv[1]);
printf("Set session hostname to %s\n", intf->session->hostname);
}
else if (!strncmp(argv[0], "user", 4) || !strncmp(argv[0], "username", 8)) {
else if (strncmp(argv[0], "user", 4) == 0 ||
strncmp(argv[0], "username", 8) == 0) {
ipmi_intf_session_set_username(intf, argv[1]);
printf("Set session username to %s\n", intf->session->username);
}
else if (!strncmp(argv[0], "pass", 4) || !strncmp(argv[0], "password", 8)) {
else if (strncmp(argv[0], "pass", 4) == 0 ||
strncmp(argv[0], "password", 8) == 0) {
ipmi_intf_session_set_password(intf, argv[1]);
printf("Set session password\n");
}
else if (!strncmp(argv[0], "authtype", 8)) {
unsigned char authtype;
authtype = (unsigned char)str2val(argv[1], ipmi_authtype_session_vals);
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], "authtype", 8) == 0) {
int authtype;
authtype = str2val(argv[1], ipmi_authtype_session_vals);
if (authtype < 0) {
lprintf(LOG_ERR, "Invalid authtype: %s", argv[1]);
} else {
ipmi_intf_session_set_authtype(intf, authtype);
printf("Set session authtype to %s\n",
val2str(intf->session->authtype_set, ipmi_authtype_session_vals));
}
}
else if (!strncmp(argv[0], "privlvl", 7)) {
unsigned char privlvl;
privlvl = (unsigned char)str2val(argv[1], ipmi_privlvl_vals);
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], "privlvl", 7) == 0) {
int privlvl;
privlvl = str2val(argv[1], ipmi_privlvl_vals);
if (privlvl < 0) {
lprintf(LOG_ERR, "Invalid privilege level: %s", argv[1]);
} else {
ipmi_intf_session_set_privlvl(intf, privlvl);
printf("Set session privilege level to %s\n",
val2str(intf->session->privlvl, ipmi_privlvl_vals));
}
}
else if (!strncmp(argv[0], "port", 4)) {
else if (strncmp(argv[0], "port", 4) == 0) {
int port = atoi(argv[1]);
ipmi_intf_session_set_port(intf, port);
printf("Set session port to %d\n", intf->session->port);
}
else if (!strncmp(argv[0], "localaddr", 9)) {
intf->my_addr = (unsigned char)strtol(argv[1], NULL, 0);
else if (strncmp(argv[0], "localaddr", 9) == 0) {
intf->my_addr = (uint8_t)strtol(argv[1], NULL, 0);
printf("Set local IPMB address to 0x%02x\n", intf->my_addr);
}
else if (!strncmp(argv[0], "targetaddr", 10)) {
intf->target_addr = (unsigned char)strtol(argv[1], NULL, 0);
else if (strncmp(argv[0], "targetaddr", 10) == 0) {
intf->target_addr = (uint8_t)strtol(argv[1], NULL, 0);
printf("Set remote IPMB address to 0x%02x\n", intf->target_addr);
}
else {
@ -247,23 +275,23 @@ int ipmi_exec_main(struct ipmi_intf * intf, int argc, char ** argv)
{
FILE * fp;
char buf[EXEC_BUF_SIZE];
char * ptr, * tok, * ret;
char * ptr, * tok, * ret, * tmp;
int __argc, i, r;
char * __argv[EXEC_ARG_SIZE];
int rc=0;
if (argc < 1) {
printf("Usage: exec <filename>\n");
lprintf(LOG_ERR, "Usage: exec <filename>");
return -1;
}
fp = ipmi_open_file_read(argv[0]);
if (!fp)
if (fp == NULL)
return -1;
while (!feof(fp)) {
while (feof(fp) == 0) {
ret = fgets(buf, EXEC_BUF_SIZE, fp);
if (!ret)
if (ret == NULL)
continue;
/* clip off optional comment tail indicated by # */
@ -273,6 +301,29 @@ int ipmi_exec_main(struct ipmi_intf * intf, int argc, char ** argv)
else
ptr = buf + strlen(buf);
/* change "" and '' with spaces in the middle to ~
* 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 */
ptr--;
while (isspace(*ptr) && ptr >= buf)
@ -280,16 +331,38 @@ int ipmi_exec_main(struct ipmi_intf * intf, int argc, char ** argv)
ptr = buf;
while (isspace(*ptr))
ptr++;
if (!strlen(ptr))
if (strlen(ptr) == 0)
continue;
/* parse it and make argument list */
__argc = 0;
tok = strtok(ptr, " ");
while (tok) {
if (__argc < EXEC_ARG_SIZE)
for (tok = strtok(ptr, " "); tok != NULL; tok = strtok(NULL, " ")) {
if (__argc < EXEC_ARG_SIZE) {
__argv[__argc++] = strdup(tok);
tok = strtok(NULL, " ");
if (__argv[__argc-1] == NULL) {
lprintf(LOG_ERR, "ipmitool: malloc failure");
return -1;
}
tmp = __argv[__argc-1];
if (*tmp == '\'') {
memmove(tmp, tmp+1, strlen(tmp));
while (*tmp != '\'') {
if (*tmp == '~')
*tmp = ' ';
tmp++;
}
*tmp = '\0';
}
if (*tmp == '"') {
memmove(tmp, tmp+1, strlen(tmp));
while (*tmp != '"') {
if (*tmp == '~')
*tmp = ' ';
tmp++;
}
*tmp = '\0';
}
}
}
/* now run the command, save the result if not successful */
@ -307,6 +380,6 @@ int ipmi_exec_main(struct ipmi_intf * intf, int argc, char ** argv)
}
fclose(fp);
return 0;
return rc;
}

View File

@ -1,6 +1,9 @@
/*
* Copyright (c) 2003, 2004 Sun Microsystems, Inc. All Rights Reserved.
*
* Copyright (c) 2004 Sun Microsystems, Inc. All Rights Reserved.
* Use is subject to license terms.
*/
/*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@ -49,23 +52,29 @@
#include <ipmitool/ipmi_sdr.h>
#include <ipmitool/ipmi_sel.h>
#include <ipmitool/ipmi_fru.h>
#include <ipmitool/ipmi_isol.h>
#include <ipmitool/ipmi_sol.h>
#include <ipmitool/ipmi_isol.h>
#include <ipmitool/ipmi_lanp.h>
#include <ipmitool/ipmi_chassis.h>
#include <ipmitool/ipmi_bmc.h>
#include <ipmitool/ipmi_mc.h>
#include <ipmitool/ipmi_sensor.h>
#include <ipmitool/ipmi_channel.h>
#include <ipmitool/ipmi_session.h>
#include <ipmitool/ipmi_event.h>
#include <ipmitool/ipmi_user.h>
#include <ipmitool/ipmi_raw.h>
#include <ipmitool/ipmi_pef.h>
#include <ipmitool/ipmi_oem.h>
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#define OPTION_STRING "I:hVvcgEaH:P:f:U:p:L:A:t:m:"
#ifdef __sun
# define OPTION_STRING "I:hVvcH:f:U:p:"
#else
# define OPTION_STRING "I:hVvcgsEao:H:P:f:U:p:C:L:A:t:m:"
#endif
int csv_output = 0;
int verbose = 0;
@ -74,168 +83,216 @@ extern const struct valstr ipmi_privlvl_vals[];
extern const struct valstr ipmi_authtype_session_vals[];
/* defined in ipmishell.c */
#ifdef HAVE_READLINE
extern int ipmi_shell_main(struct ipmi_intf * intf, int argc, char ** argv);
#endif
extern int ipmi_set_main(struct ipmi_intf * intf, int argc, char ** argv);
extern int ipmi_exec_main(struct ipmi_intf * intf, int argc, char ** argv);
struct ipmi_cmd {
int (*func)(struct ipmi_intf * intf, int argc, char ** argv);
char * name;
char * desc;
const char * name;
const char * desc;
} ipmi_cmd_list[] = {
{ ipmi_raw_main, "raw", "Send a RAW IPMI request and print response" },
{ ipmi_lanp_main, "lan", "Configure LAN Channels" },
{ ipmi_chassis_main, "chassis", "Get chassis status and set power state" },
{ ipmi_event_main, "event", "Send pre-defined events to BMC" },
{ ipmi_bmc_main, "bmc", "Print BMC status and configure global enables" },
{ ipmi_sdr_main, "sdr", "Print Sensor Data Repository entries and readings" },
{ ipmi_sensor_main, "sensor", "Print detailed sensor information" },
{ ipmi_fru_main, "fru", "Print built-in FRU and scan SDR for FRU locators" },
{ ipmi_sel_main, "sel", "Print System Evelnt Log" },
{ ipmi_sol_main, "sol", "Configure IPMIv2.0 Serial-over-LAN" },
{ ipmi_isol_main, "isol", "Configure Intel IPMIv1.5 Serial-over-LAN" },
{ ipmi_user_main, "user", "Configure BMC users" },
{ ipmi_channel_main, "channel", "Configure BMC channels" },
{ ipmi_session_main, "session", "Print session information" },
{ ipmi_shell_main, "shell", "Launch interactive IPMI shell" },
{ ipmi_exec_main, "exec", "Run list of commands from file" },
{ ipmi_set_main, "set", "Set runtime variable for shell and exec" },
{ ipmi_raw_main, "raw", "Send a RAW IPMI request and print response" },
{ ipmi_lanp_main, "lan", "Configure LAN Channels" },
{ ipmi_chassis_main, "chassis", "Get chassis status and set power state" },
{ ipmi_event_main, "event", "Send pre-defined events to MC" },
{ ipmi_mc_main, "mc", "Management Controller status and global enables" },
{ ipmi_mc_main, "bmc", NULL }, /* for backwards compatibility */
{ ipmi_sdr_main, "sdr", "Print Sensor Data Repository entries and readings" },
{ ipmi_sensor_main, "sensor", "Print detailed sensor information" },
{ ipmi_fru_main, "fru", "Print built-in FRU and scan SDR for FRU locators" },
{ ipmi_sel_main, "sel", "Print System Event Log (SEL)" },
{ ipmi_pef_main, "pef", "Configure Platform Event Filtering (PEF)" },
{ ipmi_sol_main, "sol", "Configure IPMIv2.0 Serial-over-LAN" },
{ ipmi_isol_main, "isol", "Configure IPMIv1.5 Serial-over-LAN" },
{ ipmi_user_main, "user", "Configure Management Controller users" },
{ ipmi_channel_main, "channel", "Configure Management Controller channels" },
{ ipmi_session_main, "session", "Print session information" },
#ifdef HAVE_READLINE
{ ipmi_shell_main, "shell", "Launch interactive IPMI shell" },
#endif
{ ipmi_exec_main, "exec", "Run list of commands from file" },
{ ipmi_set_main, "set", "Set runtime variable for shell and exec" },
{ NULL },
};
/*
* Print all the commands in the above table to stdout
* Print all the commands in the above table to stderr
* used for help text on command line and shell
*/
void ipmi_cmd_print(void)
void
ipmi_cmd_print(void)
{
struct ipmi_cmd * cmd;
printf("Commands:\n");
for (cmd=ipmi_cmd_list; cmd->func; cmd++) {
if (!cmd->desc)
lprintf(LOG_NOTICE, "Commands:");
for (cmd=ipmi_cmd_list; cmd->func != NULL; cmd++) {
if (cmd->desc == NULL)
continue;
printf("\t%-12s %s\n", cmd->name, cmd->desc);
lprintf(LOG_NOTICE, "\t%-12s %s", cmd->name, cmd->desc);
}
printf("\n");
lprintf(LOG_NOTICE, "");
}
/*
* Run a command from ipmi_cmd_list based on parameters.
/* ipmi_cmd_run - run a command from list based on parameters
* called from main()
*
* 1. iterate through ipmi_cmd_list matching on name
* 2. call func() for that command
*
* @intf: ipmi interface
* @name: command name
* @argc: command argument count
* @argv: command argument list
*
* returns value from func() of that commnad if found
* returns -1 if command is not found
*/
int ipmi_cmd_run(struct ipmi_intf * intf, char * name, int argc, char ** argv)
int
ipmi_cmd_run(struct ipmi_intf * intf, char * name, int argc, char ** argv)
{
struct ipmi_cmd * cmd;
for (cmd=ipmi_cmd_list; cmd->func; cmd++) {
if (!strncmp(name, cmd->name, strlen(cmd->name)))
for (cmd=ipmi_cmd_list; cmd->func != NULL; cmd++) {
if (strncmp(name, cmd->name, strlen(cmd->name)) == 0)
break;
}
if (!cmd->func) {
printf("Invalid command: %s\n", name);
if (cmd->func == NULL) {
lprintf(LOG_ERR, "Invalid command: %s", name);
return -1;
}
return cmd->func(intf, argc, argv);
}
static void ipmitool_usage(void)
/* ipmitool_usage - print usage help
*/
static void
ipmitool_usage(void)
{
printf("ipmitool version %s\n", VERSION);
printf("\n");
printf("usage: ipmitool [options...] <command>\n");
printf("\n");
printf(" -h This help\n");
printf(" -V Show version information\n");
printf(" -v Verbose (can use multiple times)\n");
printf(" -c Display output in comma separated format\n");
printf(" -I intf Interface to use\n");
printf(" -H hostname Remote host name for LAN interface\n");
printf(" -p port Remote RMCP port [default=623]\n");
printf(" -L level Remote session privilege level [default=USER]\n");
printf(" -A authtype Force use of authentication type NONE, PASSWORD, MD2 or MD5\n");
printf(" -U username Remote session username\n");
printf(" -P password Remote session password\n");
printf(" -f file Read remote session password from file\n");
printf(" -a Prompt for remote password\n");
printf(" -E Read password from IPMI_PASSWORD environment variable\n");
printf(" -m address Set local IPMB address\n");
printf(" -t address Bridge request to remote target address\n");
printf("\n");
lprintf(LOG_NOTICE, "ipmitool version %s\n", VERSION);
lprintf(LOG_NOTICE, "usage: ipmitool [options...] <command>\n");
lprintf(LOG_NOTICE, " -h This help");
lprintf(LOG_NOTICE, " -V Show version information");
lprintf(LOG_NOTICE, " -v Verbose (can use multiple times)");
lprintf(LOG_NOTICE, " -c Display output in comma separated format");
lprintf(LOG_NOTICE, " -I intf Interface to use");
lprintf(LOG_NOTICE, " -H hostname Remote host name for LAN interface");
lprintf(LOG_NOTICE, " -p port Remote RMCP port [default=623]");
lprintf(LOG_NOTICE, " -U username Remote session username");
lprintf(LOG_NOTICE, " -f file Read remote session password from file");
lprintf(LOG_NOTICE, " -C ciphersuite Cipher suite to be used by lanplus interface");
#ifndef __sun
lprintf(LOG_NOTICE, " -L level Remote session privilege level [default=USER]");
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, " -a Prompt for remote password");
lprintf(LOG_NOTICE, " -E Read password from IPMI_PASSWORD environment variable");
lprintf(LOG_NOTICE, " -m address Set local IPMB address");
lprintf(LOG_NOTICE, " -t address Bridge request to remote target address");
lprintf(LOG_NOTICE, " -o oemtype Setup for OEM (use 'list' to see available OEM types)");
#endif
lprintf(LOG_NOTICE, "");
ipmi_intf_print();
ipmi_cmd_print();
}
static char * ipmi_password_file_read(char * filename)
/* ipmi_password_file_read - Open file and read password from it
*
* @filename: file name to read from
*
* returns pointer to allocated buffer containing password
* (caller is expected to free when finished)
* returns NULL on error
*/
static char *
ipmi_password_file_read(char * filename)
{
FILE * fp;
char * pass = NULL;
int l;
pass = malloc(16);
if (!pass)
if (pass == NULL) {
lprintf(LOG_ERR, "ipmitool: malloc failure");
return NULL;
}
fp = ipmi_open_file_read((const char *)filename);
if (!fp)
if (fp == NULL) {
lprintf(LOG_ERR, "Unable to open password file %s",
filename);
return NULL;
}
/* read in id */
if (fgets(pass, 16, fp) == NULL) {
lprintf(LOG_ERR, "Unable to read password from file %s",
filename);
fclose(fp);
return NULL;
}
/* remove trailing whitespace */
l = strcspn(pass, " \r\n\t");
if (l > 0)
if (l > 0) {
pass[l] = '\0';
}
fclose(fp);
return pass;
}
int main(int argc, char ** argv)
int
main(int argc, char ** argv)
{
struct ipmi_intf * intf = NULL;
unsigned char privlvl = 0;
unsigned char target_addr = 0;
unsigned char my_addr = 0;
unsigned char authtype = 0;
uint8_t privlvl = 0;
uint8_t target_addr = 0;
uint8_t my_addr = 0;
int authtype = -1;
char * tmp = NULL;
char * hostname = NULL;
char * username = NULL;
char * password = NULL;
char * intfname = NULL;
char * progname = NULL;
char * oemtype = NULL;
int port = 0;
int cipher_suite_id = 3; /* See table 22-19 of the IPMIv2 spec */
int argflag, i;
int rc = 0;
int thump = 0;
int rc = -1;
/* save program name */
if (!(progname = strrchr(argv[0], '/')))
progname = argv[0];
else
progname++;
progname = strrchr(argv[0], '/');
progname = ((progname == NULL) ? argv[0] : progname);
while ((argflag = getopt(argc, (char **)argv, OPTION_STRING)) != -1)
{
switch (argflag) {
case 'I':
intfname = strdup(optarg);
if (intfname == NULL) {
lprintf(LOG_ERR, "ipmitool: malloc failure");
goto out_free;
}
break;
case 'h':
ipmitool_usage();
rc = 0;
goto out_free;
break;
case 'V':
printf("%s version %s\n", progname, VERSION);
rc = 0;
goto out_free;
break;
case 'g':
thump = 1;
case 'p':
port = atoi(optarg);
break;
case 'C':
cipher_suite_id = atoi(optarg);
break;
case 'v':
verbose++;
@ -245,70 +302,115 @@ int main(int argc, char ** argv)
break;
case 'H':
hostname = strdup(optarg);
break;
case 'P':
if (password)
free(password);
password = strdup(optarg);
/* Prevent password snooping with ps */
i = strlen (optarg);
memset (optarg, 'X', i);
if (hostname == NULL) {
lprintf(LOG_ERR, "ipmitool: malloc failure");
goto out_free;
}
break;
case 'f':
if (password)
free(password);
password = ipmi_password_file_read(optarg);
if (!password)
printf("Unable to read password from file %s.\n", optarg);
if (password == NULL)
lprintf(LOG_ERR, "Unable to read password "
"from file %s", optarg);
break;
case 'a':
#ifdef HAVE_GETPASSPHRASE
tmp = getpassphrase("Password: ");
#else
tmp = getpass("Password: ");
#endif
if (tmp != NULL) {
if (password)
free(password);
password = strdup(tmp);
if (password == NULL) {
lprintf(LOG_ERR, "ipmitool: malloc failure");
goto out_free;
}
}
break;
case 'U':
username = strdup(optarg);
if (username == NULL) {
lprintf(LOG_ERR, "ipmitool: malloc failure");
goto out_free;
}
break;
#ifndef __sun /* some options not enabled on solaris yet */
case 'o':
oemtype = strdup(optarg);
if (oemtype == NULL) {
lprintf(LOG_ERR, "ipmitool: malloc failure");
goto out_free;
}
if (strncmp(oemtype, "list", 4) == 0) {
ipmi_oem_print();
goto out_free;
}
break;
case 'g':
/* backwards compatible oem hack */
oemtype = strdup("intelwv2");
break;
case 's':
/* backwards compatible oem hack */
oemtype = strdup("supermicro");
break;
case 'P':
if (password)
free(password);
password = strdup(optarg);
if (password == NULL) {
lprintf(LOG_ERR, "ipmitool: malloc failure");
goto out_free;
}
/* Prevent password snooping with ps */
i = strlen(optarg);
memset(optarg, 'X', i);
break;
case 'E':
if ((tmp = getenv ("IPMITOOL_PASSWORD")))
if ((tmp = getenv("IPMITOOL_PASSWORD")))
{
if (password)
free(password);
password = strdup(tmp);
if (password == NULL) {
lprintf(LOG_ERR, "ipmitool: malloc failure");
goto out_free;
}
}
else if ((tmp = getenv("IPMI_PASSWORD")))
{
if (password)
free(password);
password = strdup(tmp);
if (password == NULL) {
lprintf(LOG_ERR, "ipmitool: malloc failure");
goto out_free;
}
}
else printf("Unable to read password from environment.\n");
break;
case 'a':
#ifdef HAVE_GETPASSPHRASE
if ((tmp = getpassphrase ("Password: ")))
#else
if ((tmp = getpass ("Password: ")))
#endif
{
if (password)
free(password);
password = strdup(tmp);
else {
lprintf(LOG_WARN, "Unable to read password from environment");
}
break;
case 'U':
username = strdup(optarg);
break;
case 'L':
privlvl = (unsigned char)str2val(optarg, ipmi_privlvl_vals);
privlvl = (uint8_t)str2val(optarg, ipmi_privlvl_vals);
if (!privlvl)
printf("Invalid privilege level %s!\n", optarg);
lprintf(LOG_WARN, "Invalid privilege level %s", optarg);
break;
case 'A':
authtype = (int)str2val(optarg, ipmi_authtype_session_vals);
break;
case 'p':
port = atoi(optarg);
break;
case 't':
target_addr = (unsigned char)strtol(optarg, NULL, 0);
target_addr = (uint8_t)strtol(optarg, NULL, 0);
break;
case 'm':
my_addr = (unsigned char)strtol(optarg, NULL, 0);
my_addr = (uint8_t)strtol(optarg, NULL, 0);
break;
#endif
default:
ipmitool_usage();
goto out_free;
@ -317,48 +419,96 @@ int main(int argc, char ** argv)
/* check for command before doing anything */
if (argc-optind <= 0) {
printf("No command provided!\n");
lprintf(LOG_ERR, "No command provided!");
ipmitool_usage();
goto out_free;
}
if (!strncmp(argv[optind], "help", 4)) {
ipmitool_usage();
if (strncmp(argv[optind], "help", 4) == 0) {
ipmi_cmd_print();
rc = 0;
goto out_free;
}
/*
* If the user has specified a hostname (-H option)
* then this is a remote access session.
*
* If no password was specified by any other method
* and the authtype was not explicitly set to NONE
* then prompt the user.
*/
if (hostname != NULL && password == NULL &&
(authtype != IPMI_SESSION_AUTHTYPE_NONE || authtype < 0)) {
#ifdef HAVE_GETPASSPHRASE
tmp = getpassphrase("Password: ");
#else
tmp = getpass("Password: ");
#endif
if (tmp != NULL) {
password = strdup(tmp);
if (password == NULL) {
lprintf(LOG_ERR, "ipmitool: malloc failure");
goto out_free;
}
}
}
/* if no interface was specified but a
* hostname was then use LAN by default
* otherwise the default is hardcoded
* to use the first entry in the list
*/
if (intfname == NULL && hostname != NULL) {
intfname = strdup("lan");
if (intfname == NULL) {
lprintf(LOG_ERR, "ipmitool: malloc failure");
goto out_free;
}
}
/* load interface */
intf = ipmi_intf_load(intfname);
if (!intf) {
printf("Error loading interface %s\n", intfname);
if (intf == NULL) {
lprintf(LOG_ERR, "Error loading interface %s", intfname);
goto out_free;
}
intf->thump = thump;
/* setup log */
log_init(progname, 0, verbose);
/* run OEM setup if found */
if (oemtype != NULL &&
ipmi_oem_setup(intf, oemtype) < 0) {
lprintf(LOG_ERR, "OEM setup for \"%s\" failed", oemtype);
goto out_free;
}
/* set session variables */
if (hostname)
if (hostname != NULL)
ipmi_intf_session_set_hostname(intf, hostname);
if (username)
if (username != NULL)
ipmi_intf_session_set_username(intf, username);
if (password)
if (password != NULL)
ipmi_intf_session_set_password(intf, password);
if (port)
if (port > 0)
ipmi_intf_session_set_port(intf, port);
if (authtype)
ipmi_intf_session_set_authtype(intf, authtype);
if (privlvl)
if (authtype >= 0)
ipmi_intf_session_set_authtype(intf, (uint8_t)authtype);
if (privlvl > 0)
ipmi_intf_session_set_privlvl(intf, privlvl);
else
ipmi_intf_session_set_privlvl(intf,
IPMI_SESSION_PRIV_ADMIN); /* default */
ipmi_intf_session_set_cipher_suite_id(intf, cipher_suite_id);
/* setup IPMB local and target address if given */
intf->my_addr = my_addr ? : IPMI_BMC_SLAVE_ADDR;
if (target_addr) {
if (target_addr > 0) {
/* need to open the interface first */
if (intf->open)
if (intf->open != NULL)
intf->open(intf);
intf->target_addr = target_addr;
/* must be admin level to do this over lan */
@ -366,22 +516,31 @@ int main(int argc, char ** argv)
}
/* now we finally run the command */
ipmi_cmd_run(intf, argv[optind], argc-optind-1, &(argv[optind+1]));
rc = ipmi_cmd_run(intf,
argv[optind],
argc-optind-1,
&(argv[optind+1]));
if (intf->opened && intf->close)
/* clean repository caches */
ipmi_cleanup(intf);
/* call interface close function if available */
if (intf->opened > 0 && intf->close != NULL)
intf->close(intf);
out_free:
log_halt();
if (intfname)
if (intfname != NULL)
free(intfname);
if (hostname)
if (hostname != NULL)
free(hostname);
if (username)
if (username != NULL)
free(username);
if (password)
if (password != NULL)
free(password);
if (oemtype != NULL)
free(oemtype);
if (rc >= 0)
exit(EXIT_SUCCESS);

View File

@ -36,8 +36,8 @@ MAINTAINERCLEANFILES = Makefile.in
INCLUDES = -I$(top_srcdir)/include
SUBDIRS = @INTF_LAN@ @INTF_LANPLUS@ @INTF_OPEN@ @INTF_LIPMI@ @INTF_IMB@
DIST_SUBDIRS = lan lanplus open lipmi imb
SUBDIRS = @INTF_LAN@ @INTF_LANPLUS@ @INTF_OPEN@ @INTF_LIPMI@ @INTF_IMB@ @INTF_BMC@
DIST_SUBDIRS = lan lanplus open lipmi imb bmc
noinst_LTLIBRARIES = libintf.la
libintf_la_SOURCES = ipmi_intf.c

View File

@ -0,0 +1,45 @@
# Copyright (c) 2004 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.
MAINTAINERCLEANFILES = Makefile.in
INCLUDES = -I$(top_srcdir)/include
EXTRA_LTLIBRARIES = libintf_bmc.la
noinst_LTLIBRARIES = @INTF_BMC_LIB@
libintf_bmc_la_LIBADD = $(top_builddir)/lib/libipmitool.la
libintf_bmc_la_SOURCES = \
bmc.c bmc.h \
bmc_intf.h

View File

@ -0,0 +1,349 @@
/*
* Copyright (c) 2004 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.
*/
/*
* interface routines between ipmitool and the bmc kernel driver
*/
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stropts.h>
#include <stddef.h>
#include <stropts.h>
#include <ipmitool/ipmi.h>
#include <ipmitool/ipmi_intf.h>
#include "bmc_intf.h"
#include "bmc.h"
static int curr_seq;
static int bmc_method(int fd, int *if_type);
struct ipmi_rs *(*sendrecv_fn)(struct ipmi_intf *, struct ipmi_rq *) = NULL;
extern int verbose;
static void dump_request(bmc_req_t *request);
static void dump_response(bmc_rsp_t *response);
static struct ipmi_rs *ipmi_bmc_send_cmd_ioctl(struct ipmi_intf *intf,
struct ipmi_rq *req);
static struct ipmi_rs *ipmi_bmc_send_cmd_putmsg(struct ipmi_intf *intf,
struct ipmi_rq *req);
#define MESSAGE_BUFSIZE 1024
struct ipmi_intf ipmi_bmc_intf = {
name: "bmc",
desc: "IPMI v2.0 BMC interface",
open: ipmi_bmc_open,
close: ipmi_bmc_close,
sendrecv: ipmi_bmc_send_cmd};
void
ipmi_bmc_close(struct ipmi_intf *intf)
{
if (intf && intf->fd >= 0)
close(intf->fd);
intf->opened = 0;
intf->fd = -1;
}
int
ipmi_bmc_open(struct ipmi_intf *intf)
{
int method;
if (!intf)
return -1;
/* Open local device */
intf->fd = open(BMC_DEV, O_RDWR);
if (intf->fd <= 0) {
perror("Could not open bmc device");
return (-1);
}
curr_seq = 0;
intf->opened = 1;
if (bmc_method(intf->fd, &method) < 0) {
perror("Could not determine bmc messaging interface");
return (-1);
}
sendrecv_fn = (method == BMC_PUTMSG_METHOD) ?
ipmi_bmc_send_cmd_putmsg : ipmi_bmc_send_cmd_ioctl;
return (intf->fd);
}
struct ipmi_rs *
ipmi_bmc_send_cmd(struct ipmi_intf *intf, struct ipmi_rq *req)
{
/* If not already opened open the device or network connection */
if (!intf->opened && intf->open && intf->open(intf) < 0)
return NULL;
/* sendrecv_fn cannot be NULL at this point */
return ((*sendrecv_fn)(intf, req));
}
static struct ipmi_rs *
ipmi_bmc_send_cmd_ioctl(struct ipmi_intf *intf, struct ipmi_rq *req)
{
struct strioctl istr;
static struct bmc_reqrsp reqrsp;
static struct ipmi_rs rsp;
memset(&reqrsp, 0, sizeof (reqrsp));
reqrsp.req.fn = req->msg.netfn;
reqrsp.req.lun = 0;
reqrsp.req.cmd = req->msg.cmd;
reqrsp.req.datalength = req->msg.data_len;
memcpy(reqrsp.req.data, req->msg.data, req->msg.data_len);
reqrsp.rsp.datalength = RECV_MAX_PAYLOAD_SIZE;
istr.ic_cmd = IOCTL_IPMI_KCS_ACTION;
istr.ic_timout = 0;
istr.ic_dp = (char *)&reqrsp;
istr.ic_len = sizeof (struct bmc_reqrsp);
if (verbose) {
printf("--\n");
dump_request(&reqrsp.req);
printf("--\n");
}
if (ioctl(intf->fd, I_STR, &istr) < 0) {
perror("BMC IOCTL: I_STR");
return (NULL);
}
if (verbose > 2) {
dump_response(&reqrsp.rsp);
printf("--\n");
}
memset(&rsp, 0, sizeof (struct ipmi_rs));
rsp.ccode = reqrsp.rsp.ccode;
rsp.data_len = reqrsp.rsp.datalength;
/* Decrement for sizeof lun, cmd and ccode */
rsp.data_len -= 3;
if (!rsp.ccode && (rsp.data_len > 0))
memcpy(rsp.data, reqrsp.rsp.data, rsp.data_len);
return (&rsp);
}
static struct ipmi_rs *
ipmi_bmc_send_cmd_putmsg(struct ipmi_intf *intf, struct ipmi_rq *req)
{
struct strbuf sb;
int flags = 0;
static uint32_t msg_seq = 0;
/*
* The length of the message structure is equal to the size of the
* bmc_req_t structure, PLUS any additional data space in excess of
* the data space already reserved in the data member + <n> for
* the rest of the members in the bmc_msg_t structure.
*/
int msgsz = offsetof(bmc_msg_t, msg) + sizeof(bmc_req_t) +
((req->msg.data_len > SEND_MAX_PAYLOAD_SIZE) ?
(req->msg.data_len - SEND_MAX_PAYLOAD_SIZE) : 0);
bmc_msg_t *msg = malloc(msgsz);
bmc_req_t *request = (bmc_req_t *)&msg->msg[0];
bmc_rsp_t *response;
static struct ipmi_rs rsp;
struct ipmi_rs *ret = NULL;
msg->m_type = BMC_MSG_REQUEST;
msg->m_id = msg_seq++;
request->fn = req->msg.netfn;
request->lun = 0;
request->cmd = req->msg.cmd;
request->datalength = req->msg.data_len;
memcpy(request->data, req->msg.data, req->msg.data_len);
sb.len = msgsz;
sb.buf = (unsigned char *)msg;
if (verbose) {
printf("--\n");
dump_request(request);
printf("--\n");
}
if (putmsg(intf->fd, NULL, &sb, 0) < 0) {
perror("BMC putmsg: ");
free(msg);
return (NULL);
}
free(msg);
sb.buf = malloc(MESSAGE_BUFSIZE);
sb.maxlen = MESSAGE_BUFSIZE;
if (getmsg(intf->fd, NULL, &sb, &flags) < 0) {
perror("BMC getmsg: ");
free(sb.buf);
return (NULL);
}
msg = (bmc_msg_t *)sb.buf;
if (verbose > 3) {
printf("Got msg (id 0x%x) type 0x%x\n", msg->m_id, msg->m_type);
}
/* Did we get an error back from the stream? */
switch (msg->m_type) {
case BMC_MSG_RESPONSE:
response = (bmc_rsp_t *)&msg->msg[0];
if (verbose > 2) {
dump_response(response);
printf("--\n");
}
memset(&rsp, 0, sizeof (struct ipmi_rs));
rsp.ccode = response->ccode;
rsp.data_len = response->datalength;
if (!rsp.ccode && (rsp.data_len > 0))
memcpy(rsp.data, response->data, rsp.data_len);
ret = &rsp;
break;
case BMC_MSG_ERROR:
/* In case of an error, msg->msg[0] has the error code */
printf("bmc_send_cmd: %s\n", strerror(msg->msg[0]));
break;
}
free(sb.buf);
return (ret);
}
/*
* Determine which interface to use. Returns the interface method
* to use.
*/
static int
bmc_method(int fd, int *if_type)
{
struct strioctl istr;
int retval = 0;
uint8_t method = BMC_PUTMSG_METHOD;
istr.ic_cmd = IOCTL_IPMI_INTERFACE_METHOD;
istr.ic_timout = 0;
istr.ic_dp = (uint8_t *)&method;
istr.ic_len = 1;
/*
* If the ioctl doesn't exist, we should get an EINVAL back.
* Bail out on any other error.
*/
if (ioctl(fd, I_STR, &istr) < 0) {
if (errno != EINVAL)
retval = -1;
else
method = BMC_IOCTL_METHOD;
}
if (retval == 0)
*if_type = method;
return (retval);
}
static void
dump_request(bmc_req_t *request)
{
int i;
printf("BMC req.fn : 0x%x\n", request->fn);
printf("BMC req.lun : 0x%x\n", request->lun);
printf("BMC req.cmd : 0x%x\n", request->cmd);
printf("BMC req.datalength : 0x%x\n", request->datalength);
printf("BMC req.data : ");
if (request->datalength > 0) {
for (i = 0; i < request->datalength; i++)
printf("0x%x ", request->data[i]);
} else {
printf("<NONE>");
}
printf("\n");
}
static void
dump_response(bmc_rsp_t *response)
{
int i;
printf("BMC rsp.fn : 0x%x\n", response->fn);
printf("BMC rsp.lun : 0x%x\n", response->lun);
printf("BMC rsp.cmd : 0x%x\n", response->cmd);
printf("BMC rsp.ccode : 0x%x\n", response->ccode);
printf("BMC rsp.datalength : 0x%x\n", response->datalength);
printf("BMC rsp.data : ");
if (response->datalength > 0) {
for (i = 0; i < response->datalength; i++)
printf("0x%x ", response->data[i]);
} else {
printf("<NONE>");
}
printf("\n");
}

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2004 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_BMC_H_
#define _IPMI_BMC_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <ipmitool/ipmi.h>
#define BMC_DEV "/dev/bmc"
struct ipmi_rs *ipmi_bmc_send_cmd(struct ipmi_intf *intf, struct ipmi_rq *req);
int ipmi_bmc_open(struct ipmi_intf *intf);
void ipmi_bmc_close(struct ipmi_intf *intf);
#ifdef __cplusplus
}
#endif
#endif /* _IPMI_BMC_H_ */

View File

@ -0,0 +1,211 @@
/*
* Copyright (c) 2004 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 _BMC_INTF_H
#define _BMC_INTF_H
#pragma ident "@(#)bmc_intf.h 1.2 05/03/07 SMI"
#ifdef __cplusplus
extern "C" {
#endif
#define BMC_SUCCESS 0x0
#define BMC_FAILURE 0x1
#define BMC_NETFN_CHASSIS 0x0
#define BMC_NETFN_BRIDGE 0x2
#define BMC_NETFN_SE 0x4
#define BMC_NETFN_APP 0x6
#define BMC_NETFN_FIRMWARE 0x8
#define BMC_NETFN_STORAGE 0xa
#define BMC_NETFN_TRANSPORT 0xc
#define SEND_MAX_PAYLOAD_SIZE 34 /* MAX payload */
#define RECV_MAX_PAYLOAD_SIZE 33 /* MAX payload */
#define BMC_MIN_RESPONSE_SIZE 3
#define BMC_MIN_REQUEST_SIZE 2
#define BMC_MAX_RESPONSE_SIZE (BMC_MIN_RESPONSE_SIZE + RECV_MAX_PAYLOAD_SIZE)
#define BMC_MAX_REQUEST_SIZE (BMC_MIN_REQUEST_SIZE + BMC_MAX_RESPONSE_SIZE)
#define BUF_SIZE 256
#define MAX_BUF_SIZE 256
/*
* Useful macros
*/
#define FORM_NETFNLUN(net, lun) ((((net) << 2) | ((lun) & 0x3)))
#define GET_NETFN(netfn) (((netfn) >> 2) & 0x3f)
#define GET_LUN(netfn) (netfn & 0x3)
#define RESP_NETFN(nflun) ((nflun) | 1)
#define ISREQUEST(nl) (((nl) & 1) == 0) /* test for request */
#define ISRESPONSE(nl) (((nl) & 1) == 1) /* test for response */
/* for checking BMC specific stuff */
#define BMC_GET_DEVICE_ID 0x1 /* GET DEVICE ID COMMAND */
#define BMC_IPMI_15_VER 0x51 /* IPMI 1.5 definion */
/* BMC Completion Code and OEM Completion Code */
#define BMC_IPMI_UNSPECIFIC_ERROR 0xFF /* Unspecific Error */
#define BMC_IPMI_INVALID_COMMAND 0xC1 /* Invalid Command */
#define BMC_IPMI_COMMAND_TIMEOUT 0xC3 /* Command Timeout */
#define BMC_IPMI_DATA_LENGTH_EXCEED 0xC8 /* DataLength exceeded limit */
#define BMC_IPMI_OEM_FAILURE_SENDBMC 0x7E /* Cannot send BMC req */
#define IOCTL_IPMI_KCS_ACTION 0x01
#define IOCTL_IPMI_INTERFACE_METHOD 0x02
/* Interface methods returned from IOCTL_IPMI_INTERFACE_METHOD ioctl: */
#define BMC_IOCTL_METHOD 0 /* Not returned from ioctl, */
/* but can be used by */
/* applications that want to */
/* compare against an */
/* alternative method. */
#define BMC_PUTMSG_METHOD 1
/*
* bmc_req_t is the data structure to send
* request packet from applications to the driver
* module.
*
* the request pkt is mainly for KCS-interface-BMC
* messages. Since the system interface is session-less
* connections, the packet won't have any session
* information.
*
* the data payload will be 2 bytes less than max
* BMC supported packet size.
* the address of the responder is always BMC and so
* rsSa field is not required.
*/
typedef struct bmc_req {
uint8_t fn; /* netFn for command */
uint8_t lun; /* logical unit on responder */
uint8_t cmd; /* command */
uint8_t datalength; /* length of following data */
uint8_t data[SEND_MAX_PAYLOAD_SIZE]; /* request data */
} bmc_req_t;
/*
* bmc_rsp_t is the data structure to send
* respond packet from applications to the driver
* module.
*
* the respond pkt is mainly for KCS-interface-BMC
* messages. Since the system interface is session-less
* connections, the packet won't have any session
* information.
*
* the data payload will be 2 bytes less than max
* BMC supported packet size.
*/
typedef struct bmc_rsp {
uint8_t fn; /* netFn for command */
uint8_t lun; /* logical unit on responder */
uint8_t cmd; /* command */
uint8_t ccode; /* completion code */
uint8_t datalength; /* Length */
uint8_t data[RECV_MAX_PAYLOAD_SIZE]; /* response */
} bmc_rsp_t;
/*
* the data structure for synchronous operation via ioctl (DEPRECATED)
*/
typedef struct bmc_reqrsp {
bmc_req_t req; /* request half */
bmc_rsp_t rsp; /* response half */
} bmc_reqrsp_t;
/*
* 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;
/*
* An error response passed back from the bmc driver will have its m_id
* field set to BMC_UNKNOWN_MSG_ID if a message is sent to it that is not
* at least as large as a bmc_msg_t.
*/
#define BMC_UNKNOWN_MSG_ID ~((uint32_t)0)
/*
* Possible values for the m_type field in bmc_msg_t:
*/
#define BMC_MSG_REQUEST 1 /* BMC request (as above, sent to the */
/* driver by the user), bmc_msg.msg */
/* begins with the bmc_req_t */
/* structure. */
#define BMC_MSG_RESPONSE 2 /* BMC response (sent by the driver) */
/* bmc_msg.msg begins with the */
/* bmc_rsp_t structure. */
#define BMC_MSG_ERROR 3 /* Error while processing a user msg */
/* msg[0] is the error code */
/* (interpret as an errno value) */
#ifdef __cplusplus
}
#endif
#endif /* _BMC_INTF_H */

View File

@ -41,6 +41,8 @@
#include <config.h>
#include <ipmitool/ipmi_intf.h>
#include <ipmitool/ipmi.h>
#include <ipmitool/ipmi_sdr.h>
#include <ipmitool/log.h>
#ifdef IPMI_INTF_OPEN
extern struct ipmi_intf ipmi_open_intf;
@ -51,6 +53,9 @@ extern struct ipmi_intf ipmi_imb_intf;
#ifdef IPMI_INTF_LIPMI
extern struct ipmi_intf ipmi_lipmi_intf;
#endif
#ifdef IPMI_INTF_BMC
extern struct ipmi_intf ipmi_bmc_intf;
#endif
#ifdef IPMI_INTF_LAN
extern struct ipmi_intf ipmi_lan_intf;
#endif
@ -68,6 +73,9 @@ struct ipmi_intf * ipmi_intf_table[] = {
#ifdef IPMI_INTF_LIPMI
&ipmi_lipmi_intf,
#endif
#ifdef IPMI_INTF_BMC
&ipmi_bmc_intf,
#endif
#ifdef IPMI_INTF_LAN
&ipmi_lan_intf,
#endif
@ -77,98 +85,150 @@ struct ipmi_intf * ipmi_intf_table[] = {
NULL
};
/* ipmi_intf_print - Print list of interfaces
*
* no meaningful return code
*/
void ipmi_intf_print(void)
{
struct ipmi_intf ** intf;
int def = 1;
printf("Interfaces:\n");
lprintf(LOG_NOTICE, "Interfaces:");
for (intf = ipmi_intf_table; intf && *intf; intf++) {
printf("\t%-12s %s", (*intf)->name, (*intf)->desc);
if (def) {
printf(" [default]");
def = 0;
}
printf("\n");
lprintf(LOG_NOTICE, "\t%-12s %s %s",
(*intf)->name, (*intf)->desc,
def ? "[default]" : "");
def = 0;
}
printf("\n");
lprintf(LOG_NOTICE, "");
}
/* Load an interface from the interface table above
* If no interface name is given return first entry
/* ipmi_intf_load - Load an interface from the interface table above
* If no interface name is given return first entry
*
* @name: interface name to try and load
*
* returns pointer to inteface structure if found
* returns NULL on error
*/
struct ipmi_intf * ipmi_intf_load(char * name)
{
struct ipmi_intf ** intf;
struct ipmi_intf * i;
if (!name) {
if (name == NULL) {
i = ipmi_intf_table[0];
if (i->setup && (i->setup(i) < 0)) {
printf("ERROR: Unable to setup interface %s\n", name);
if (i->setup != NULL && (i->setup(i) < 0)) {
lprintf(LOG_ERR, "Unable to setup "
"interface %s", name);
return NULL;
}
return i;
}
for (intf = ipmi_intf_table; intf && *intf ; intf++) {
for (intf = ipmi_intf_table;
((intf != NULL) && (*intf != NULL));
intf++) {
i = *intf;
if (!strncmp(name, i->name, strlen(name))) {
if (i->setup && (i->setup(i) < 0)) {
printf("ERROR: Unable to setup interface %s\n", name);
if (strncmp(name, i->name, strlen(name)) == 0) {
if (i->setup != NULL && (i->setup(i) < 0)) {
lprintf(LOG_ERR, "Unable to setup "
"interface %s", name);
return NULL;
}
return i;
}
}
return NULL;
}
void ipmi_intf_session_set_hostname(struct ipmi_intf * intf, char * hostname)
void
ipmi_intf_session_set_hostname(struct ipmi_intf * intf, char * hostname)
{
if (intf && intf->session) {
memset(intf->session->hostname, 0, 16);
if (hostname)
memcpy(intf->session->hostname, hostname, min(strlen(hostname), 64));
if (intf->session == NULL)
return;
memset(intf->session->hostname, 0, 16);
if (hostname != NULL) {
memcpy(intf->session->hostname, hostname,
__min(strlen(hostname), 64));
}
}
void ipmi_intf_session_set_username(struct ipmi_intf * intf, char * username)
void
ipmi_intf_session_set_username(struct ipmi_intf * intf, char * username)
{
if (intf && intf->session) {
memset(intf->session->username, 0, 16);
if (username)
memcpy(intf->session->username, username, min(strlen(username), 16));
}
if (intf->session == NULL)
return;
memset(intf->session->username, 0, 16);
if (username == NULL)
return;
memcpy(intf->session->username, username, __min(strlen(username), 16));
}
void ipmi_intf_session_set_password(struct ipmi_intf * intf, char * password)
void
ipmi_intf_session_set_password(struct ipmi_intf * intf, char * password)
{
if (intf && intf->session) {
memset(intf->session->authcode, 0, 16);
if (intf->session == NULL)
return;
memset(intf->session->authcode, 0, IPMI_AUTHCODE_BUFFER_SIZE);
if (password == NULL) {
intf->session->password = 0;
if (password) {
intf->session->password = 1;
memcpy(intf->session->authcode, password, min(strlen(password), 16));
}
return;
}
intf->session->password = 1;
memcpy(intf->session->authcode, password,
__min(strlen(password), IPMI_AUTHCODE_BUFFER_SIZE));
}
void ipmi_intf_session_set_privlvl(struct ipmi_intf * intf, unsigned char level)
void
ipmi_intf_session_set_privlvl(struct ipmi_intf * intf, uint8_t level)
{
if (intf && intf->session)
intf->session->privlvl = level;
if (intf->session == NULL)
return;
intf->session->privlvl = level;
}
void ipmi_intf_session_set_port(struct ipmi_intf * intf, int port)
void
ipmi_intf_session_set_cipher_suite_id(struct ipmi_intf * intf, uint8_t cipher_suite_id)
{
if (intf && intf->session)
intf->session->port = port;
if (intf->session == NULL)
return;
intf->session->cipher_suite_id = cipher_suite_id;
}
void ipmi_intf_session_set_authtype(struct ipmi_intf * intf, unsigned char authtype)
void
ipmi_intf_session_set_port(struct ipmi_intf * intf, int port)
{
if (intf && intf->session)
intf->session->authtype_set = authtype;
if (intf->session == NULL)
return;
intf->session->port = port;
}
void
ipmi_intf_session_set_authtype(struct ipmi_intf * intf, uint8_t authtype)
{
if (intf->session == NULL)
return;
intf->session->authtype_set = authtype;
}
void
ipmi_cleanup(struct ipmi_intf * intf)
{
ipmi_sdr_list_empty(intf);
}

View File

@ -61,13 +61,13 @@ static const struct valstr asf_type_vals[] __attribute__((unused)) = {
/* ASF message header */
struct asf_hdr {
unsigned long iana;
unsigned char type;
unsigned char tag;
unsigned char __reserved;
unsigned char len;
uint32_t iana;
uint8_t type;
uint8_t tag;
uint8_t __reserved;
uint8_t len;
} __attribute__((packed));
int handle_asf(struct ipmi_intf * intf, unsigned char * data, int data_len);
int handle_asf(struct ipmi_intf * intf, uint8_t * data, int data_len);
#endif /* IPMI_ASF_H */

View File

@ -66,11 +66,11 @@
*
* Use OpenSSL implementation of MD5 algorithm if found
*/
unsigned char * ipmi_auth_md5(struct ipmi_session * s, unsigned char * data, int data_len)
uint8_t * ipmi_auth_md5(struct ipmi_session * s, uint8_t * data, int data_len)
{
#ifdef HAVE_CRYPTO_MD5
MD5_CTX ctx;
static unsigned char md[16];
static uint8_t md[16];
uint32_t temp;
#if WORDS_BIGENDIAN
@ -82,11 +82,11 @@ unsigned char * ipmi_auth_md5(struct ipmi_session * s, unsigned char * data, int
memset(&ctx, 0, sizeof(MD5_CTX));
MD5_Init(&ctx);
MD5_Update(&ctx, (const unsigned char *)s->authcode, 16);
MD5_Update(&ctx, (const unsigned char *)&s->session_id, 4);
MD5_Update(&ctx, (const unsigned char *)data, data_len);
MD5_Update(&ctx, (const unsigned char *)&temp, sizeof(uint32_t));
MD5_Update(&ctx, (const unsigned char *)s->authcode, 16);
MD5_Update(&ctx, (const uint8_t *)s->authcode, 16);
MD5_Update(&ctx, (const uint8_t *)&s->session_id, 4);
MD5_Update(&ctx, (const uint8_t *)data, data_len);
MD5_Update(&ctx, (const uint8_t *)&temp, sizeof(uint32_t));
MD5_Update(&ctx, (const uint8_t *)s->authcode, 16);
MD5_Final(md, &ctx);
if (verbose > 3)
@ -130,11 +130,11 @@ unsigned char * ipmi_auth_md5(struct ipmi_session * s, unsigned char * data, int
* Use OpenSSL implementation of MD2 algorithm if found.
* This function is analogous to ipmi_auth_md5
*/
unsigned char * ipmi_auth_md2(struct ipmi_session * s, unsigned char * data, int data_len)
uint8_t * ipmi_auth_md2(struct ipmi_session * s, uint8_t * data, int data_len)
{
#ifdef HAVE_CRYPTO_MD2
MD2_CTX ctx;
static unsigned char md[16];
static uint8_t md[16];
uint32_t temp;
#if WORDS_BIGENDIAN
@ -146,11 +146,11 @@ unsigned char * ipmi_auth_md2(struct ipmi_session * s, unsigned char * data, int
memset(&ctx, 0, sizeof(MD2_CTX));
MD2_Init(&ctx);
MD2_Update(&ctx, (const unsigned char *)s->authcode, 16);
MD2_Update(&ctx, (const unsigned char *)&s->session_id, 4);
MD2_Update(&ctx, (const unsigned char *)data, data_len);
MD2_Update(&ctx, (const unsigned char *)&temp, sizeof(uint32_t));
MD2_Update(&ctx, (const unsigned char *)s->authcode, 16);
MD2_Update(&ctx, (const uint8_t *)s->authcode, 16);
MD2_Update(&ctx, (const uint8_t *)&s->session_id, 4);
MD2_Update(&ctx, (const uint8_t *)data, data_len);
MD2_Update(&ctx, (const uint8_t *)&temp, sizeof(uint32_t));
MD2_Update(&ctx, (const uint8_t *)s->authcode, 16);
MD2_Final(md, &ctx);
if (verbose > 3)
@ -158,10 +158,67 @@ unsigned char * ipmi_auth_md2(struct ipmi_session * s, unsigned char * data, int
return md;
#else /*HAVE_CRYPTO_MD2*/
static unsigned char md[16];
static uint8_t md[16];
memset(md, 0, 16);
printf("WARNING: No internal support for MD2! "
"Please re-compile with OpenSSL.\n");
return md;
#endif /*HAVE_CRYPTO_MD2*/
}
/* special authentication method */
uint8_t * ipmi_auth_special(struct ipmi_session * s)
{
#ifdef HAVE_CRYPTO_MD5
MD5_CTX ctx;
static uint8_t md[16];
uint8_t challenge[16];
int i;
memset(challenge, 0, 16);
memset(md, 0, 16);
memset(&ctx, 0, sizeof(MD5_CTX));
MD5_Init(&ctx);
MD5_Update(&ctx, (const uint8_t *)s->authcode, strlen(s->authcode));
MD5_Final(md, &ctx);
for (i=0; i<16; i++)
challenge[i] = s->challenge[i] ^ md[i];
memset(md, 0, 16);
memset(&ctx, 0, sizeof(MD5_CTX));
MD5_Init(&ctx);
MD5_Update(&ctx, (const uint8_t *)challenge, 16);
MD5_Final(md, &ctx);
return md;
#else /*HAVE_CRYPTO_MD5*/
int i;
md5_state_t state;
static md5_byte_t digest[16];
uint8_t challenge[16];
memset(challenge, 0, 16);
memset(digest, 0, 16);
memset(&state, 0, sizeof(md5_state_t));
md5_init(&state);
md5_append(&state, (const md5_byte_t *)s->authcode, strlen(s->authcode));
md5_finish(&state, digest);
for (i=0; i<16; i++)
challenge[i] = s->challenge[i] ^ digest[i];
memset(digest, 0, 16);
memset(&state, 0, sizeof(md5_state_t));
md5_init(&state);
md5_append(&state, (const md5_byte_t *)challenge, 16);
md5_finish(&state, digest);
return digest;
#endif /*HAVE_CRYPTO_MD5*/
}

View File

@ -37,7 +37,8 @@
#ifndef IPMI_AUTH_H
#define IPMI_AUTH_H
unsigned char * ipmi_auth_md2(struct ipmi_session * s, unsigned char * data, int data_len);
unsigned char * ipmi_auth_md5(struct ipmi_session * s, unsigned char * data, int data_len);
uint8_t * ipmi_auth_md2(struct ipmi_session * s, uint8_t * data, int data_len);
uint8_t * ipmi_auth_md5(struct ipmi_session * s, uint8_t * data, int data_len);
uint8_t * ipmi_auth_special(struct ipmi_session * s);
#endif /*IPMI_AUTH_H*/

File diff suppressed because it is too large Load Diff

View File

@ -53,7 +53,7 @@ struct ipmi_rs * ipmi_lan_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req
int ipmi_lan_send_rsp(struct ipmi_intf * intf, struct ipmi_rs * rsp);
int ipmi_lan_open(struct ipmi_intf * intf);
void ipmi_lan_close(struct ipmi_intf * intf);
void ipmi_get_channel_info(struct ipmi_intf * intf, unsigned char channel);
void ipmi_get_channel_info(struct ipmi_intf * intf, uint8_t channel);
int ipmi_lan_ping(struct ipmi_intf * intf);
extern struct ipmi_intf ipmi_lan_intf;

View File

@ -39,6 +39,7 @@
#include <ipmitool/helper.h>
#include "lan.h"
#include "asf.h"
#define RMCP_VERSION_1 0x06
@ -69,12 +70,22 @@ static const struct valstr rmcp_class_vals[] __attribute__((unused)) = {
/* RMCP message header */
struct rmcp_hdr {
unsigned char ver;
unsigned char __reserved;
unsigned char seq;
unsigned char class;
uint8_t ver;
uint8_t __reserved;
uint8_t seq;
uint8_t class;
} __attribute__((packed));
int handle_rmcp(struct ipmi_intf * intf, unsigned char * data, int data_len);
struct rmcp_pong {
struct rmcp_hdr rmcp;
struct asf_hdr asf;
uint32_t iana;
uint32_t oem;
uint8_t sup_entities;
uint8_t sup_interact;
uint8_t reserved[6];
} __attribute__((packed));
int handle_rmcp(struct ipmi_intf * intf, uint8_t * data, int data_len);
#endif /* IPMI_RMCP_H */

View File

@ -61,13 +61,13 @@ static const struct valstr asf_type_vals[] __attribute__((unused)) = {
/* ASF message header */
struct asf_hdr {
unsigned long iana;
unsigned char type;
unsigned char tag;
unsigned char __reserved;
unsigned char len;
uint32_t iana;
uint8_t type;
uint8_t tag;
uint8_t __reserved;
uint8_t len;
} __attribute__((packed));
int handle_asf(struct ipmi_intf * intf, unsigned char * data, int data_len);
int handle_asf(struct ipmi_intf * intf, uint8_t * data, int data_len);
#endif /* IPMI_ASF_H */

File diff suppressed because it is too large Load Diff

View File

@ -80,23 +80,6 @@
#define IPMI_PRIV_OEM 5
/* From table 13-17 of the IPMI v2 specification */
#define IPMI_AUTH_RAKP_NONE 0x00
#define IPMI_AUTH_RAKP_HMAC_SHA1 0x01
#define IPMI_AUTH_RAKP_HMAC_MD5 0x02
/* From table 13-18 of the IPMI v2 specification */
#define IPMI_INTEGRITY_NONE 0x00
#define IPMI_INTEGRITY_HMAC_SHA1_96 0x01
#define IPMI_INTEGRITY_HMAC_MD5_128 0x02
#define IPMI_INTEGRITY_MD5_128 0x03
/* From table 13-19 of the IPMI v2 specfication */
#define IPMI_CRYPT_NONE 0x00
#define IPMI_CRYPT_AES_CBC_128 0x01
#define IPMI_CRYPT_XRC4_128 0x02
#define IPMI_CRYPT_XRC4_40 0x03
#define IPMI_CRYPT_AES_CBC_128_BLOCK_SIZE 0x10
@ -115,7 +98,7 @@
* TODO: these are wild guesses and should be checked
*/
#define IPMI_MAX_CONF_HEADER_SIZE 0x20
#define IPMI_MAX_PAYLOAD_SIZE 0xFF /* Includes confidentiality header/trailer */
#define IPMI_MAX_PAYLOAD_SIZE 0xFFFF /* Includes confidentiality header/trailer */
#define IPMI_MAX_CONF_TRAILER_SIZE 0x20
#define IPMI_MAX_INTEGRITY_PAD_SIZE 0x20
#define IPMI_MAX_AUTH_CODE_SIZE 0x20
@ -129,7 +112,7 @@
* one integrity algorithm, and 1 encyrption alogrithm
*/
#define IPMI_OPEN_SESSION_REQUEST_SIZE 32
#define IPMI_RAKP1_MESSAGE_SIZE 43
#define IPMI_RAKP1_MESSAGE_SIZE 44
#define IPMI_RAKP3_MESSAGE_MAX_SIZE 28
#define IPMI_MAX_USER_NAME_LENGTH 16

View File

@ -38,6 +38,7 @@
#include <string.h>
#include <config.h>
#include <ipmitool/bswap.h>
#include <ipmitool/log.h>
#include "lanplus.h"
#include "lanplus_crypt.h"
#include "lanplus_crypt_impl.h"
@ -70,20 +71,21 @@
* 1 on failure (the authcode does not match)
*/
int lanplus_rakp2_hmac_matches(const struct ipmi_session * session,
const unsigned char * bmc_mac)
const uint8_t * bmc_mac,
struct ipmi_intf * intf)
{
char * buffer;
int bufferLength, i;
unsigned char mac[20];
int macLength;
uint8_t mac[20];
uint32_t macLength;
unsigned int SIDm_lsbf, SIDc_lsbf;
uint32_t SIDm_lsbf, SIDc_lsbf;
if (session->v2_data.auth_alg == IPMI_AUTH_RAKP_NONE)
return 1;
/* We don't yet support other alogrithms */
/* We don't yet support other algorithms */
assert(session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_SHA1);
@ -98,6 +100,10 @@ int lanplus_rakp2_hmac_matches(const struct ipmi_session * session,
strlen(session->username); /* optional */
buffer = malloc(bufferLength);
if (buffer == NULL) {
lprintf(LOG_ERR, "ipmitool: malloc failure");
return 1;
}
/*
* Fill the buffer. I'm assuming that we're using the LSBF representation of the
@ -162,19 +168,17 @@ int lanplus_rakp2_hmac_matches(const struct ipmi_session * session,
printbuf((char*)(session->authcode), IPMI_AUTHCODE_BUFFER_SIZE, ">> rakp2 mac key");
}
/*
* The buffer is complete. Let's hash.
*/
lanplus_HMAC(session->v2_data.auth_alg,
session->authcode,
(session->authcode[IPMI_AUTHCODE_BUFFER_SIZE] == 0?
strlen(session->authcode): IPMI_AUTHCODE_BUFFER_SIZE),
IPMI_AUTHCODE_BUFFER_SIZE,
buffer,
bufferLength,
mac,
&macLength);
free(buffer);
@ -206,25 +210,36 @@ int lanplus_rakp2_hmac_matches(const struct ipmi_session * session,
*
* If the authentication algorithm is IPMI_AUTH_RAKP_NONE, we return success.
*
* return 0 on success (the authcode matches)
* 1 on failure (the authcode does not match)
* return 1 on success (the authcode matches)
* 0 on failure (the authcode does not match)
*
*/
int lanplus_rakp4_hmac_matches(const struct ipmi_session * session,
const unsigned char * bmc_mac)
const uint8_t * bmc_mac,
struct ipmi_intf * intf)
{
char * buffer;
int bufferLength, i;
unsigned char mac[20];
int macLength;
uint8_t mac[20];
uint32_t macLength;
unsigned int SIDc_lsbf;
uint32_t SIDc_lsbf;
if (session->v2_data.auth_alg == IPMI_AUTH_RAKP_NONE)
return 1;
/* We don't yet support other alogrithms */
assert(session->v2_data.auth_alg == IPMI_INTEGRITY_HMAC_SHA1_96);
if (ipmi_oem_active(intf, "intelplus")){
/* Intel BMC responds with the integrity Algorithm in RAKP4 */
if (session->v2_data.integrity_alg == IPMI_INTEGRITY_NONE)
return 1;
/* We don't yet support other algorithms */
assert(session->v2_data.integrity_alg == IPMI_INTEGRITY_HMAC_SHA1_96);
} else {
if (session->v2_data.auth_alg == IPMI_AUTH_RAKP_NONE)
return 1;
/* We don't yet support other algorithms */
assert(session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_SHA1);
}
bufferLength =
16 + /* Rm */
@ -232,6 +247,10 @@ int lanplus_rakp4_hmac_matches(const struct ipmi_session * session,
16; /* GUIDc */
buffer = (char*)malloc(bufferLength);
if (buffer == NULL) {
lprintf(LOG_ERR, "ipmitool: malloc failure");
return 1;
}
/*
* Fill the buffer. I'm assuming that we're using the LSBF representation of the
@ -276,9 +295,11 @@ int lanplus_rakp4_hmac_matches(const struct ipmi_session * session,
/*
* The buffer is complete. Let's hash.
*/
lanplus_HMAC(session->v2_data.auth_alg,
lanplus_HMAC((ipmi_oem_active(intf, "intelplus"))
? session->v2_data.integrity_alg
: session->v2_data.auth_alg ,
session->v2_data.sik,
20,
IPMI_SIK_BUFFER_SIZE,
buffer,
bufferLength,
mac,
@ -286,7 +307,8 @@ int lanplus_rakp4_hmac_matches(const struct ipmi_session * session,
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");
}
@ -323,12 +345,13 @@ int lanplus_rakp4_hmac_matches(const struct ipmi_session * session,
*/
int lanplus_generate_rakp3_authcode(char * output_buffer,
const struct ipmi_session * session,
unsigned int * mac_length)
uint32_t * mac_length,
struct ipmi_intf * intf)
{
int ret = 0;
int input_buffer_length, i;
char * input_buffer;
unsigned int SIDm_lsbf;
uint32_t SIDm_lsbf;
if (session->v2_data.auth_alg == IPMI_AUTH_RAKP_NONE)
@ -337,7 +360,7 @@ int lanplus_generate_rakp3_authcode(char * output_buffer,
return 0;
}
/* We don't yet support other alogrithms */
/* We don't yet support other algorithms */
assert(session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_SHA1);
input_buffer_length =
@ -348,6 +371,10 @@ int lanplus_generate_rakp3_authcode(char * output_buffer,
strlen(session->username);
input_buffer = malloc(input_buffer_length);
if (input_buffer == NULL) {
lprintf(LOG_ERR, "ipmitool: malloc failure");
return 1;
}
/*
* Fill the buffer. I'm assuming that we're using the LSBF representation of the
@ -371,7 +398,10 @@ int lanplus_generate_rakp3_authcode(char * output_buffer,
memcpy(input_buffer + 16, &SIDm_lsbf, 4);
/* 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 */
input_buffer[21] = strlen(session->username);
@ -386,11 +416,9 @@ int lanplus_generate_rakp3_authcode(char * output_buffer,
printbuf((char*)(session->authcode), IPMI_AUTHCODE_BUFFER_SIZE, ">> rakp3 mac key");
}
lanplus_HMAC(session->v2_data.auth_alg,
session->authcode,
(session->authcode[IPMI_AUTHCODE_BUFFER_SIZE - 1] == 0?
strlen(session->authcode): IPMI_AUTHCODE_BUFFER_SIZE),
IPMI_AUTHCODE_BUFFER_SIZE,
input_buffer,
input_buffer_length,
output_buffer,
@ -438,8 +466,7 @@ int lanplus_generate_sik(struct ipmi_session * session)
char * input_buffer;
int input_buffer_length, i;
char * input_key;
int input_key_length;
int mac_length;
uint32_t mac_length;
memset(session->v2_data.sik, 0, IPMI_SIK_BUFFER_SIZE);
@ -447,7 +474,7 @@ int lanplus_generate_sik(struct ipmi_session * session)
if (session->v2_data.auth_alg == IPMI_AUTH_RAKP_NONE)
return 0;
/* We don't yet support other alogrithms */
/* We don't yet support other algorithms */
assert(session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_SHA1);
input_buffer_length =
@ -458,6 +485,10 @@ int lanplus_generate_sik(struct ipmi_session * session)
strlen(session->username);
input_buffer = malloc(input_buffer_length);
if (input_buffer == NULL) {
lprintf(LOG_ERR, "ipmitool: malloc failure");
return 1;
}
/*
* Fill the buffer. I'm assuming that we're using the LSBF representation of the
@ -501,24 +532,24 @@ int lanplus_generate_sik(struct ipmi_session * session)
* using Kg. It specifies that Kg should not be truncated, but I
* do not know what is meant by that.
*/
printf("lanplus_generate_sik: We dont yet support hashing with Kg");
lprintf(LOG_ERR, "lanplus_generate_sik: We dont yet support hashing with Kg");
assert(0);
input_key = session->v2_data.kg;
input_key_length = strlen(session->v2_data.kg);
}
else
{
/* We will be hashing with Kuid */
input_key = session->authcode;
input_key_length = (session->authcode[IPMI_AUTHCODE_BUFFER_SIZE - 1] == 0?
strlen(session->authcode): IPMI_AUTHCODE_BUFFER_SIZE);
}
if (verbose >= 2)
printbuf(input_buffer, input_buffer_length, "session integrity key input");
lanplus_HMAC(session->v2_data.auth_alg,
input_key,
input_key_length,
IPMI_AUTHCODE_BUFFER_SIZE,
input_buffer,
input_buffer_length,
session->v2_data.sik,
@ -554,9 +585,9 @@ int lanplus_generate_sik(struct ipmi_session * session)
*/
int lanplus_generate_k1(struct ipmi_session * session)
{
unsigned int mac_length;
uint32_t mac_length;
unsigned char CONST_1[] =
uint8_t CONST_1[] =
{0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01};
@ -566,7 +597,7 @@ int lanplus_generate_k1(struct ipmi_session * session)
{
lanplus_HMAC(session->v2_data.auth_alg,
session->v2_data.sik,
20, /* SIK length */
IPMI_SIK_BUFFER_SIZE, /* SIK length */
CONST_1,
20,
session->v2_data.k1,
@ -597,9 +628,9 @@ int lanplus_generate_k1(struct ipmi_session * session)
*/
int lanplus_generate_k2(struct ipmi_session * session)
{
unsigned int mac_length;
uint32_t mac_length;
unsigned char CONST_2[] =
uint8_t CONST_2[] =
{0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02};
@ -609,7 +640,7 @@ int lanplus_generate_k2(struct ipmi_session * session)
{
lanplus_HMAC(session->v2_data.auth_alg,
session->v2_data.sik,
20, /* SIK length */
IPMI_SIK_BUFFER_SIZE, /* SIK length */
CONST_2,
20,
session->v2_data.k2,
@ -645,20 +676,19 @@ int lanplus_generate_k2(struct ipmi_session * session)
* returns 0 on success
* 1 on failure
*/
int lanplus_encrypt_payload(unsigned char crypt_alg,
const unsigned char * key,
const unsigned char * input,
unsigned int input_length,
unsigned char * output,
unsigned short * bytes_written)
int lanplus_encrypt_payload(uint8_t crypt_alg,
const uint8_t * key,
const uint8_t * input,
uint32_t input_length,
uint8_t * output,
uint16_t * bytes_written)
{
unsigned char * padded_input;
unsigned int mod, i, bytes_encrypted;
unsigned char pad_length = 0;
uint8_t * padded_input;
uint32_t mod, i, bytes_encrypted;
uint8_t pad_length = 0;
if (crypt_alg == IPMI_CRYPT_NONE)
{
printf("NOT ENCRYPTING\n");
/* Just copy the input to the output */
*bytes_written = input_length;
return 0;
@ -666,7 +696,7 @@ int lanplus_encrypt_payload(unsigned char crypt_alg,
/* Currently, we only support AES */
assert(crypt_alg == IPMI_CRYPT_AES_CBC_128);
assert(input_length <= 255);
assert(input_length <= IPMI_MAX_PAYLOAD_SIZE);
/*
@ -678,7 +708,11 @@ int lanplus_encrypt_payload(unsigned char crypt_alg,
if (mod)
pad_length = IPMI_CRYPT_AES_CBC_128_BLOCK_SIZE - mod;
padded_input = (unsigned char*)malloc(input_length + pad_length + 1);
padded_input = (uint8_t*)malloc(input_length + pad_length + 1);
if (padded_input == NULL) {
lprintf(LOG_ERR, "ipmitool: malloc failure");
return 1;
}
memcpy(padded_input, input, input_length);
/* add the pad */
@ -691,8 +725,7 @@ int lanplus_encrypt_payload(unsigned char crypt_alg,
/* Generate an initialization vector, IV, for the encryption process */
if (lanplus_rand(output, IPMI_CRYPT_AES_CBC_128_BLOCK_SIZE))
{
printf("lanplus_encrypt_payload: Error generating IV\n");
assert(0);
lprintf(LOG_ERR, "lanplus_encrypt_payload: Error generating IV");
return 1;
}
@ -745,9 +778,9 @@ int lanplus_encrypt_payload(unsigned char crypt_alg,
int lanplus_has_valid_auth_code(struct ipmi_rs * rs,
struct ipmi_session * session)
{
unsigned char * bmc_authcode;
unsigned char generated_authcode[IPMI_MAX_MAC_SIZE];
unsigned int generated_authcode_length;
uint8_t * bmc_authcode;
uint8_t generated_authcode[IPMI_MAX_MAC_SIZE];
uint32_t generated_authcode_length;
if ((rs->session.authtype != IPMI_SESSION_AUTHTYPE_RMCP_PLUS) ||
@ -766,7 +799,7 @@ int lanplus_has_valid_auth_code(struct ipmi_rs * rs,
lanplus_HMAC(session->v2_data.integrity_alg,
session->v2_data.k1,
20,
IPMI_AUTHCODE_BUFFER_SIZE,
rs->data + IMPI_LANPLUS_OFFSET_AUTHTYPE,
rs->data_len - IMPI_LANPLUS_OFFSET_AUTHTYPE - IPMI_SHA1_AUTHCODE_SIZE,
generated_authcode,
@ -774,7 +807,7 @@ int lanplus_has_valid_auth_code(struct ipmi_rs * rs,
if (verbose > 3)
{
printf("Validating authcode\n");
lprintf(LOG_DEBUG+2, "Validating authcode");
printbuf(session->v2_data.k1, 20, "K1");
printbuf(rs->data + IMPI_LANPLUS_OFFSET_AUTHTYPE,
rs->data_len - IMPI_LANPLUS_OFFSET_AUTHTYPE - IPMI_SHA1_AUTHCODE_SIZE,
@ -802,15 +835,15 @@ int lanplus_has_valid_auth_code(struct ipmi_rs * rs,
* returns 0 on success (we were able to successfully decrypt the packet)
* 1 on failure (we were unable to successfully decrypt the packet)
*/
int lanplus_decrypt_payload(unsigned char crypt_alg,
const unsigned char * key,
const unsigned char * input,
unsigned int input_length,
unsigned char * output,
unsigned short * payload_size)
int lanplus_decrypt_payload(uint8_t crypt_alg,
const uint8_t * key,
const uint8_t * input,
uint32_t input_length,
uint8_t * output,
uint16_t * payload_size)
{
unsigned char * decrypted_payload;
unsigned int bytes_decrypted;
uint8_t * decrypted_payload;
uint32_t bytes_decrypted;
if (crypt_alg == IPMI_CRYPT_NONE)
{
@ -823,7 +856,12 @@ int lanplus_decrypt_payload(unsigned char crypt_alg,
/* We only support AES */
assert(crypt_alg == IPMI_CRYPT_AES_CBC_128);
decrypted_payload = (unsigned char*)malloc(input_length);
decrypted_payload = (uint8_t*)malloc(input_length);
if (decrypted_payload == NULL) {
lprintf(LOG_ERR, "ipmitool: malloc failure");
return 1;
}
lanplus_decrypt_aes_cbc_128(input, /* IV */
key, /* Key */
@ -837,7 +875,7 @@ int lanplus_decrypt_payload(unsigned char crypt_alg,
if (bytes_decrypted != 0)
{
/* Success */
unsigned char conf_pad_length;
uint8_t conf_pad_length;
int i;
memmove(output,
@ -859,14 +897,14 @@ int lanplus_decrypt_payload(unsigned char crypt_alg,
{
if (decrypted_payload[*payload_size + i] == i)
{
printf("ERROR: Malformed payload padding\n");
lprintf(LOG_ERR, "Malformed payload padding");
assert(0);
}
}
}
else
{
printf("ERROR: lanplus_decrypt_aes_cbc_128 decryptd 0 bytes\n");
lprintf(LOG_ERR, "ERROR: lanplus_decrypt_aes_cbc_128 decryptd 0 bytes");
assert(0);
}

View File

@ -41,30 +41,35 @@
/*
* See the implementation file for documentation
* ipmi_intf can be used for oem specific implementations
* e.g. if (ipmi_oem_active(intf, "OEM_XYZ"))
*/
int lanplus_rakp2_hmac_matches(const struct ipmi_session * session,
const unsigned char * hmac);
const uint8_t * hmac,
struct ipmi_intf * intf);
int lanplus_rakp4_hmac_matches(const struct ipmi_session * session,
const unsigned char * hmac);
const uint8_t * hmac,
struct ipmi_intf * intf);
int lanplus_generate_rakp3_authcode(char * buffer,
const struct ipmi_session * session,
unsigned int * auth_length);
uint32_t * auth_length,
struct ipmi_intf * intf);
int lanplus_generate_sik(struct ipmi_session * session);
int lanplus_generate_k1(struct ipmi_session * session);
int lanplus_generate_k2(struct ipmi_session * session);
int lanplus_encrypt_payload(unsigned char crypt_alg,
const unsigned char * key,
const unsigned char * input,
unsigned int input_length,
unsigned char * output,
unsigned short * bytesWritten);
int lanplus_decrypt_payload(unsigned char crypt_alg,
const unsigned char * key,
const unsigned char * input,
unsigned int input_length,
unsigned char * output,
unsigned short * payload_size);
int lanplus_encrypt_payload(uint8_t crypt_alg,
const uint8_t * key,
const uint8_t * input,
uint32_t input_length,
uint8_t * output,
uint16_t * bytesWritten);
int lanplus_decrypt_payload(uint8_t crypt_alg,
const uint8_t * key,
const uint8_t * input,
uint32_t input_length,
uint8_t * output,
uint16_t * payload_size);
int lanplus_has_valid_auth_code(struct ipmi_rs * rs,
struct ipmi_session * session);

View File

@ -34,6 +34,7 @@
* facility.
*/
#include "ipmitool/ipmi_constants.h"
#include "lanplus.h"
#include "lanplus_crypt_impl.h"
#include <openssl/hmac.h>
@ -54,7 +55,7 @@
* returns 0 on success
* 1 on failure
*/
int lanplus_seed_prng(unsigned int bytes)
int lanplus_seed_prng(uint32_t bytes)
{
if (! RAND_load_file("/dev/urandom", bytes))
return 1;
@ -77,9 +78,9 @@ int lanplus_seed_prng(unsigned int bytes)
* 1 on failure
*/
int
lanplus_rand(unsigned char * buffer, unsigned int 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
/*
@ -111,14 +112,14 @@ lanplus_rand(unsigned char * buffer, unsigned int num_bytes)
*
* returns a pointer to md
*/
unsigned char *
lanplus_HMAC(unsigned char mac,
uint8_t *
lanplus_HMAC(uint8_t mac,
const void *key,
int key_len,
const unsigned char *d,
const uint8_t *d,
int n,
unsigned char *md,
unsigned int *md_len)
uint8_t *md,
uint32_t *md_len)
{
const EVP_MD *evp_md;
@ -128,12 +129,12 @@ lanplus_HMAC(unsigned char mac,
evp_md = EVP_sha1();
else
{
printf("Invalid mac type 0x%x in lanplus_HMAC\n", mac);
fprintf(stderr, "Invalid mac type 0x%x in lanplus_HMAC\n", mac);
assert(0);
}
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);
}
@ -152,17 +153,18 @@ lanplus_HMAC(unsigned char mac,
* to 0 on failure, or if 0 bytes were input.
*/
void
lanplus_encrypt_aes_cbc_128(const unsigned char * iv,
const unsigned char * key,
const unsigned char * input,
unsigned int input_length,
unsigned char * output,
unsigned int * bytes_written)
lanplus_encrypt_aes_cbc_128(const uint8_t * iv,
const uint8_t * key,
const uint8_t * input,
uint32_t input_length,
uint8_t * output,
uint32_t * bytes_written)
{
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key, iv);
EVP_CIPHER_CTX_set_padding(&ctx, 0);
*bytes_written = 0;
@ -185,7 +187,7 @@ lanplus_encrypt_aes_cbc_128(const unsigned char * iv,
assert((input_length % IPMI_CRYPT_AES_CBC_128_BLOCK_SIZE) == 0);
if(!EVP_EncryptUpdate(&ctx, output, bytes_written, input, input_length))
if(!EVP_EncryptUpdate(&ctx, output, (unsigned int *)bytes_written, input, input_length))
{
/* Error */
*bytes_written = 0;
@ -193,9 +195,9 @@ lanplus_encrypt_aes_cbc_128(const unsigned char * iv,
}
else
{
unsigned int 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;
return; /* Error */
@ -226,16 +228,18 @@ lanplus_encrypt_aes_cbc_128(const unsigned char * iv,
* to 0 on failure, or if 0 bytes were input.
*/
void
lanplus_decrypt_aes_cbc_128(const unsigned char * iv,
const unsigned char * key,
const unsigned char * input,
unsigned int input_length,
unsigned char * output,
unsigned int * bytes_written)
lanplus_decrypt_aes_cbc_128(const uint8_t * iv,
const uint8_t * key,
const uint8_t * input,
uint32_t input_length,
uint8_t * output,
uint32_t * bytes_written)
{
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key, iv);
EVP_CIPHER_CTX_set_padding(&ctx, 0);
if (verbose > 2)
@ -259,23 +263,23 @@ lanplus_decrypt_aes_cbc_128(const unsigned char * iv,
assert((input_length % IPMI_CRYPT_AES_CBC_128_BLOCK_SIZE) == 0);
if(!EVP_DecryptUpdate(&ctx, output, bytes_written, input, input_length))
if (!EVP_DecryptUpdate(&ctx, output, (unsigned int *)bytes_written, input, input_length))
{
/* Error */
printf("ERROR: decrypt update failed\n");
fprintf(stderr, "ERROR: decrypt update failed");
*bytes_written = 0;
return;
}
else
{
unsigned int 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];
ERR_error_string(ERR_get_error(), buffer);
printf("the ERR error %s\n", buffer);
printf("ERROR: decrypt final failed\n");
fprintf(stderr, "the ERR error %s", buffer);
fprintf(stderr, "ERROR: decrypt final failed");
*bytes_written = 0;
return; /* Error */
}
@ -289,7 +293,7 @@ lanplus_decrypt_aes_cbc_128(const unsigned char * iv,
if (verbose > 1)
{
printf("Decrypted %d encrypted bytes\n", input_length);
fprintf(stderr, "Decrypted %d encrypted bytes", input_length);
printbuf(output, *bytes_written, "Decrypted this data");
}
}

View File

@ -39,32 +39,32 @@
int
lanplus_seed_prng(unsigned int bytes);
lanplus_seed_prng(uint32_t bytes);
int
lanplus_rand(unsigned char * buffer, unsigned int num_bytes);
lanplus_rand(uint8_t * buffer, uint32_t num_bytes);
unsigned char *
lanplus_HMAC(unsigned char mac, const void *key, int key_len,
const unsigned char *d, int n, unsigned char *md,
unsigned int *md_len);
uint8_t *
lanplus_HMAC(uint8_t mac, const void *key, int key_len,
const uint8_t *d, int n, uint8_t *md,
uint32_t *md_len);
void
lanplus_encrypt_aes_cbc_128(const unsigned char * iv,
const unsigned char * key,
const unsigned char * input,
unsigned int input_length,
unsigned char * output,
unsigned int * bytes_written);
lanplus_encrypt_aes_cbc_128(const uint8_t * iv,
const uint8_t * key,
const uint8_t * input,
uint32_t input_length,
uint8_t * output,
uint32_t * bytes_written);
void
lanplus_decrypt_aes_cbc_128(const unsigned char * iv,
const unsigned char * key,
const unsigned char * input,
unsigned int input_length,
unsigned char * output,
unsigned int * bytes_written);
lanplus_decrypt_aes_cbc_128(const uint8_t * iv,
const uint8_t * key,
const uint8_t * input,
uint32_t input_length,
uint8_t * output,
uint32_t * bytes_written);
#endif /* IPMI_LANPLUS_CRYPT_IMPL_H */

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_encryption_algorithms[];
#define DUMP_PREFIX_INCOMING "<< "
#define DUMP_PREFIX_INCOMING "<<"
void lanplus_dump_open_session_response(const struct ipmi_rs * rsp)
{
if (verbose < 2)
return;
printf("%sOPEN SESSION RESPONSE\n", DUMP_PREFIX_INCOMING);
printf("%s Message tag : 0x%02x\n",
@ -63,6 +66,12 @@ void lanplus_dump_open_session_response(const struct ipmi_rs * rsp)
printf("%s Console Session ID : 0x%08lx\n",
DUMP_PREFIX_INCOMING,
(long)rsp->payload.open_session_response.console_id);
/* only tag, status, privlvl, and console id are returned if error */
if (rsp->payload.open_session_response.rakp_return_code !=
IPMI_RAKP_STATUS_NO_ERRORS)
return;
printf("%s BMC Session ID : 0x%08lx\n",
DUMP_PREFIX_INCOMING,
(long)rsp->payload.open_session_response.bmc_id);
@ -83,10 +92,13 @@ void lanplus_dump_open_session_response(const struct ipmi_rs * rsp)
void lanplus_dump_rakp2_message(const struct ipmi_rs * rsp, unsigned char auth_alg)
void lanplus_dump_rakp2_message(const struct ipmi_rs * rsp, uint8_t auth_alg)
{
int i;
if (verbose < 2)
return;
printf("%sRAKP 2 MESSAGE\n", DUMP_PREFIX_INCOMING);
printf("%s Message tag : 0x%02x\n",
@ -137,34 +149,27 @@ void lanplus_dump_rakp2_message(const struct ipmi_rs * rsp, unsigned char auth_a
void lanplus_dump_rakp4_message(const struct ipmi_rs * rsp, unsigned char auth_alg)
void lanplus_dump_rakp4_message(const struct ipmi_rs * rsp, uint8_t auth_alg)
{
int i;
if (verbose < 2)
return;
printf("%sRAKP 4 MESSAGE\n", DUMP_PREFIX_INCOMING);
printf("%s Message tag : 0x%02x\n",
DUMP_PREFIX_INCOMING,
rsp->payload.rakp2_message.message_tag);
rsp->payload.rakp4_message.message_tag);
printf("%s RMCP+ status : %s\n",
DUMP_PREFIX_INCOMING,
val2str(rsp->payload.rakp2_message.rakp_return_code,
val2str(rsp->payload.rakp4_message.rakp_return_code,
ipmi_rakp_return_codes));
printf("%s Console Session ID : 0x%08lx\n",
DUMP_PREFIX_INCOMING,
(long)rsp->payload.rakp2_message.console_id);
printf("%s BMC random number : 0x", DUMP_PREFIX_INCOMING);
for (i = 0; i < 16; ++i)
printf("%02x", rsp->payload.rakp2_message.bmc_rand[i]);
printf("\n");
printf("%s BMC GUID : 0x", DUMP_PREFIX_INCOMING);
for (i = 0; i < 16; ++i)
printf("%02x", rsp->payload.rakp2_message.bmc_guid[i]);
printf("\n");
(long)rsp->payload.rakp4_message.console_id);
switch(auth_alg)
{

View File

@ -42,8 +42,8 @@
/* See the implementation file for documentation */
void lanplus_dump_open_session_response(const struct ipmi_rs * rsp);
void lanplus_dump_rakp2_message(const struct ipmi_rs * rsp, unsigned char auth_alg);
void lanplus_dump_rakp4_message(const struct ipmi_rs * rsp, unsigned char auth_alg);
void lanplus_dump_rakp2_message(const struct ipmi_rs * rsp, uint8_t auth_alg);
void lanplus_dump_rakp4_message(const struct ipmi_rs * rsp, uint8_t auth_alg);
#endif /* IPMI_LANPLUS_DUMP_H */

View File

@ -1,4 +1,5 @@
#include "lanplus.h"
#include "ipmitool/ipmi_constants.h"
const struct valstr ipmi_rakp_return_codes[] = {
@ -17,7 +18,7 @@ const struct valstr ipmi_rakp_return_codes[] = {
{ IPMI_RAKP_STATUS_INVALID_NAME_LENGTH, "invalid name length" },
{ IPMI_RAKP_STATUS_UNAUTHORIZED_NAME, "unauthorized name" },
{ IPMI_RAKP_STATUS_UNAUTHORIZED_GUID, "unauthorized GUID" },
{ IPMI_RAKP_STATUS_INVALID_INTEGRITY_CHECK_VALUE, "invlalid integrity check value" },
{ IPMI_RAKP_STATUS_INVALID_INTEGRITY_CHECK_VALUE, "invalid integrity check value" },
{ IPMI_RAKP_STATUS_INVALID_CONFIDENTIALITY_ALGORITHM, "invalid confidentiality algorithm" },
{ IPMI_RAKP_STATUS_NO_CIPHER_SUITE_MATCH, "no matching cipher suite" },
{ IPMI_RAKP_STATUS_ILLEGAL_PARAMTER, "illegal parameter" },
@ -35,26 +36,4 @@ const struct valstr ipmi_priv_levels[] = {
};
const struct valstr ipmi_auth_algorithms[] = {
{ IPMI_AUTH_RAKP_NONE, "none" },
{ IPMI_AUTH_RAKP_HMAC_SHA1, "hmac_sha1" },
{ IPMI_AUTH_RAKP_HMAC_MD5, "hmac_md5" },
{ 0, 0 },
};
const struct valstr ipmi_integrity_algorithms[] = {
{ IPMI_INTEGRITY_NONE, "none" },
{ IPMI_INTEGRITY_HMAC_SHA1_96, "hmac_sha1_96" },
{ IPMI_INTEGRITY_HMAC_MD5_128, "hmac_md5_128" },
{ IPMI_INTEGRITY_MD5_128 , "md5_128" },
{ 0, 0 },
};
const struct valstr ipmi_encryption_algorithms[] = {
{ IPMI_CRYPT_NONE, "none" },
{ IPMI_CRYPT_AES_CBC_128, "aes_cbc_128" },
{ IPMI_CRYPT_XRC4_128, "xrc4_128" },
{ IPMI_CRYPT_XRC4_40, "xrc4_40" },
{ 0, 0 },
};

View File

@ -69,12 +69,12 @@ static const struct valstr rmcp_class_vals[] __attribute__((unused)) = {
/* RMCP message header */
struct rmcp_hdr {
unsigned char ver;
unsigned char __reserved;
unsigned char seq;
unsigned char class;
uint8_t ver;
uint8_t __reserved;
uint8_t seq;
uint8_t class;
} __attribute__((packed));
int handle_rmcp(struct ipmi_intf * intf, unsigned char * data, int data_len);
int handle_rmcp(struct ipmi_intf * intf, uint8_t * data, int data_len);
#endif /* IPMI_RMCP_H */

View File

@ -60,30 +60,35 @@
extern int verbose;
#define IPMI_OPENIPMI_DEV "/dev/ipmi0"
#define IPMI_OPENIPMI_DEVFS "/dev/ipmi/0"
static int ipmi_openipmi_open(struct ipmi_intf * intf)
static int
ipmi_openipmi_open(struct ipmi_intf * intf)
{
int i = 0;
intf->fd = open(IPMI_OPENIPMI_DEV, O_RDWR);
if (intf->fd < 0) {
lperror(LOG_ERR, "Could not open ipmi device");
intf->fd = open(IPMI_OPENIPMI_DEVFS, O_RDWR);
lperror(LOG_ERR, "Could not open device at %s or %s",
IPMI_OPENIPMI_DEV, IPMI_OPENIPMI_DEVFS);
return -1;
}
if (ioctl(intf->fd, IPMICTL_SET_GETS_EVENTS_CMD, &i)) {
lperror(LOG_ERR, "Could not set to get events");
if (ioctl(intf->fd, IPMICTL_SET_GETS_EVENTS_CMD, &i) < 0) {
lperror(LOG_ERR, "Could not enable event receiver");
return -1;
}
if (intf->my_addr) {
if (intf->my_addr != 0) {
unsigned int a = intf->my_addr;
if (ioctl(intf->fd, IPMICTL_SET_MY_ADDRESS_CMD, &a)) {
if (ioctl(intf->fd, IPMICTL_SET_MY_ADDRESS_CMD, &a) < 0) {
lperror(LOG_ERR, "Could not set IPMB address");
return -1;
}
lprintf(LOG_DEBUG, "Set my IPMB address to 0x%x", intf->my_addr);
lprintf(LOG_DEBUG, "Set IPMB address to 0x%x",
intf->my_addr);
}
intf->opened = 1;
@ -91,14 +96,19 @@ static int ipmi_openipmi_open(struct ipmi_intf * intf)
return intf->fd;
}
static void ipmi_openipmi_close(struct ipmi_intf * intf)
static void
ipmi_openipmi_close(struct ipmi_intf * intf)
{
if (intf && intf->fd >= 0)
if (intf->fd >= 0) {
close(intf->fd);
intf->fd = -1;
}
intf->opened = 0;
}
static struct ipmi_rs *ipmi_openipmi_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
static struct ipmi_rs *
ipmi_openipmi_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
{
struct ipmi_recv recv;
struct ipmi_addr addr;
@ -114,13 +124,15 @@ static struct ipmi_rs *ipmi_openipmi_send_cmd(struct ipmi_intf * intf, struct ip
static int curr_seq = 0;
fd_set rset;
if (!intf || !req)
return NULL;
if (!intf->opened && intf->open && intf->open(intf) < 0)
if (intf == NULL || req == NULL)
return NULL;
if (intf->opened == 0 && intf->open != NULL)
if (intf->open(intf) < 0)
return NULL;
if (verbose > 2)
printbuf(req->msg.data, req->msg.data_len, "send_cmd");
printbuf(req->msg.data, req->msg.data_len,
"OpenIPMI Request Message");
/*
* setup and send message
@ -128,17 +140,18 @@ static struct ipmi_rs *ipmi_openipmi_send_cmd(struct ipmi_intf * intf, struct ip
memset(&_req, 0, sizeof(struct ipmi_req));
if (intf->target_addr &&
if (intf->target_addr != 0 &&
intf->target_addr != intf->my_addr) {
/* use IPMB address if needed */
ipmb_addr.slave_addr = intf->target_addr;
_req.addr = (char *) &ipmb_addr;
_req.addr_len = sizeof(ipmb_addr);
lprintf(LOG_DEBUG, "Sending request to IPMB target @ 0x%x",
intf->target_addr);
lprintf(LOG_DEBUG, "Sending request to "
"IPMB target @ 0x%x", intf->target_addr);
} else {
/* otherwise use system interface */
lprintf(LOG_DEBUG+2, "Sending request to System Interface");
lprintf(LOG_DEBUG+2, "Sending request to "
"System Interface");
_req.addr = (char *) &bmc_addr;
_req.addr_len = sizeof(bmc_addr);
}
@ -150,7 +163,7 @@ static struct ipmi_rs *ipmi_openipmi_send_cmd(struct ipmi_intf * intf, struct ip
_req.msg.data_len = req->msg.data_len;
if (ioctl(intf->fd, IPMICTL_SEND_COMMAND, &_req) < 0) {
lperror(LOG_ERR, "Error sending command");
lperror(LOG_ERR, "Unable to send command");
return NULL;
}
@ -162,11 +175,11 @@ static struct ipmi_rs *ipmi_openipmi_send_cmd(struct ipmi_intf * intf, struct ip
FD_SET(intf->fd, &rset);
if (select(intf->fd+1, &rset, NULL, NULL, NULL) < 0) {
lperror(LOG_ERR, "Error doing select");
lperror(LOG_ERR, "I/O Error");
return NULL;
}
if (!FD_ISSET(intf->fd, &rset)) {
lprintf(LOG_ERR, "Error no data available");
if (FD_ISSET(intf->fd, &rset) == 0) {
lprintf(LOG_ERR, "No data available");
return NULL;
}
@ -201,7 +214,7 @@ static struct ipmi_rs *ipmi_openipmi_send_cmd(struct ipmi_intf * intf, struct ip
rsp.data_len = recv.msg.data_len - 1;
/* save response data for caller */
if (!rsp.ccode && rsp.data_len) {
if (rsp.ccode == 0 && rsp.data_len > 0) {
memmove(rsp.data, rsp.data + 1, rsp.data_len);
rsp.data[recv.msg.data_len] = 0;
}
@ -215,6 +228,7 @@ struct ipmi_intf ipmi_open_intf = {
open: ipmi_openipmi_open,
close: ipmi_openipmi_close,
sendrecv: ipmi_openipmi_send_cmd,
my_addr: IPMI_BMC_SLAVE_ADDR,
target_addr: IPMI_BMC_SLAVE_ADDR,
};