Compare commits

...

296 Commits

Author SHA1 Message Date
ca9d7f702b This commit was manufactured by cvs2svn to create tag 'IPMITOOL_1_8_5'. 2006-01-15 20:46:14 +00:00
d4a64e17f2 update version 2006-01-15 20:46:13 +00:00
e855ba03df update email address to remove sun.com 2006-01-15 20:46:00 +00:00
68cdacb211 update changelog 2006-01-15 20:39:26 +00:00
85643e52a2 byteswap port 2006-01-15 20:25:23 +00:00
776080c88a update manpage with new arguments and tsol command 2006-01-15 20:21:30 +00:00
f0cd89fea6 add missing define 2006-01-15 19:14:04 +00:00
d6e85b8427 updates from sourceforge,
changes to support settable SOL escape char
2006-01-15 06:41:08 +00:00
ed8a467f6d update tyan sol to behave like ipmiv2 sol client 2006-01-15 06:40:37 +00:00
715add8fef fix iana for supermicro, add for tyan 2006-01-14 18:43:43 +00:00
da9252ceba add supermicro oem type 2006-01-13 18:25:10 +00:00
ae1fe95cb1 Cleared set_access structure; contained garbage data 2005-12-09 19:57:48 +00:00
f42f7c701c Add support for bridged message over different channel
Ex.: In an ATCA environment, send a message through the LAN iface
to another blade present in the chassis or to an AMC bay.
Tested:
Lan.c with Kontron AT8001 with Intel CMM shelf manager
Lan.c with Kontron AT8001 with Kontron AMC's
Lanplus.c with Kontron AT8001 with Intel CMM shelf manager
Lanplus.c with Kontron AT8001 with Kontron AMC's
2005-11-28 18:45:37 +00:00
29f43931e4 * Change maximum channel size for 0x0e (current channel) 2005-11-24 16:08:51 +00:00
2ea87e639b * Add command to get and clear UDP/RMCP/IP Statistics 2005-11-24 16:04:37 +00:00
8ec87a396e * Add priv commands to set user privileges 2005-11-23 21:59:23 +00:00
cd7e75a9d5 * Fix req_seq issue with RMCP+ 2005-11-23 21:45:37 +00:00
738cf02694 On all IPMI commands, the structure ipmi_rq must be cleared (memset(&req, 0, sizeof(req)).
This was not done for the 4 commands sent.  This was causing some commands
sent to the KCS interface to have an invalid LUN.
2005-10-28 14:10:48 +00:00
f7519e00eb revert 6-bit ascii size computation 2005-09-29 18:40:04 +00:00
c546582e92 new command for Add SEL Entry on event list from file 2005-09-23 20:08:51 +00:00
22c7f92135 add event direction to output 2005-09-23 20:07:50 +00:00
f449928806 don't print builtin fru header twice 2005-09-09 23:27:11 +00:00
8a0559a651 add top-level "power" command as shortcut to chassis power commands 2005-09-09 23:19:41 +00:00
6cb97e4327 6-bit packed ascii size computation was not correctly handling strings that are not 3-byte aligned 2005-09-09 23:17:55 +00:00
a15d6a31ac - Fix a bug where the retry-count parameters was 'anded' with 0x03 instead of 0x07
See IPMI specification 2.0 rev 1.0 markup june 2004 table 26-5 parameters 4
2005-09-09 17:09:50 +00:00
77275ab616 sel version output is 4-bit bcd in a single byte 2005-09-06 22:43:10 +00:00
32c94e3eae update version to 1.8.4 2005-09-06 22:02:03 +00:00
36e388648d add 'echo' command for use in ipmi scripts 2005-09-06 22:00:45 +00:00
aac4cc9e05 remove constraint on table size, a size of 0 can actually mean just entry 0 is populated 2005-09-06 18:37:38 +00:00
c552839583 forgot to add config.h 2005-09-02 18:12:04 +00:00
9dd625a215 don't print access info for non-lan channels 2005-09-02 17:57:05 +00:00
f50160a9e4 fix portability issues 2005-09-02 17:56:27 +00:00
67a60f1c9d Adjust sel info output 2005-09-01 20:57:09 +00:00
7eeae98fb4 optimize sign extension 2005-08-27 02:26:32 +00:00
ae92538cbb fix formatting issues 2005-08-26 23:00:56 +00:00
558f279597 manufacturer id is lsb first on oem sel records 2005-08-23 20:55:09 +00:00
4e9fb18ef6 eliminate extra noise 2005-08-23 20:51:53 +00:00
dc7c60b7a8 fix segfault when BMC does not support locking 2005-08-23 20:50:15 +00:00
38d0926d9f add Tyan IPMIv1.5 SOL code, contributed by Tyan Computer Corp
it may need some work to fine tune the behavior on actual
hardware but this is the initial raw code contribution.
2005-08-23 19:09:25 +00:00
661a80433e let event specific pef policies continue to print info 2005-08-23 19:05:43 +00:00
a4c5e7bda0 revert email address change that was made 2005-08-23 19:05:14 +00:00
cf40042856 update a few strings 2005-08-23 19:03:24 +00:00
92876549ab add support for enabling/disabling lan alerting for channel; default to enabled 2005-08-23 19:02:50 +00:00
141721d220 increase timeout and limit retries to 1 for raw commands 2005-08-23 19:01:35 +00:00
1e0164c253 allow 'sel time set now' to set sel time to current client time 2005-08-23 18:59:43 +00:00
ecb214d423 add support for configuring lan alerting 2005-08-23 17:59:09 +00:00
1196369aaf let entity id be specified as string 2005-08-22 16:32:24 +00:00
bfe06ebd98 extra argument to function removed 2005-08-22 16:31:31 +00:00
58e4e355f8 fix segfault when raw command returns error 2005-08-18 23:54:27 +00:00
9d762b82a0 Recognize and decipher OEM SEL entries properly 2005-08-17 20:34:21 +00:00
9ad01e6eed fix a few gcc4 compile warnings, lots remaining... 2005-08-11 16:20:36 +00:00
53c97bc5b4 not closing session after chassis power control can be bad for session management on the bmc 2005-08-11 16:18:22 +00:00
6ab2eb972e gcc4 is very picky about signedness and event_type is only 7 bits. not sure if this is gcc bug or not. 2005-08-11 16:10:51 +00:00
e25e0b8e71 Update write_fru_area Api so both upgEkey and fru write works properly
also added some comments. And change some printf to lprintf
 - added soffset(source offset) and doffset(destination) parameters to write_fru_area
2005-07-26 14:40:23 +00:00
cfd7f610cb rename define to be more correct 2005-07-14 23:51:52 +00:00
f9d19aa0c5 fix typo and simplify string 2005-07-14 23:44:33 +00:00
6a90734a67 add sun id 2005-07-14 23:40:25 +00:00
2440c09d50 update sensor type code table 2005-07-14 23:06:45 +00:00
1f597a78e2 prevent segfault on bad SEL data 2005-07-14 21:47:20 +00:00
f4dd419fe6 -Modified read length to fit bridge message (mostly for AMC) 2005-07-14 15:56:04 +00:00
b3472220af make this function a macro 2005-07-14 00:21:26 +00:00
54d6016a31 why was this using pow? 2005-07-13 18:37:30 +00:00
864ac5ad26 Added conditionaly built GetDeviceLocator call when INCLUDE_PICMG_GET_DEVICE_LOCATOR
is defined. It doesn't allow for bridged send messages to reach AMC yet.
2005-07-12 14:49:12 +00:00
17d68a4289 Added Kontron fwum header 2005-07-12 14:47:06 +00:00
907d8b30f5 Added Kontron OEM firmware update commands 2005-07-12 14:43:56 +00:00
c2d9746775 Added Manufacturer name strings to mc info 2005-07-12 14:27:36 +00:00
51a92c0917 Corrected typo 2005-07-12 13:38:51 +00:00
07f4139e70 added selftest support 2005-07-12 13:19:03 +00:00
6514de2b13 added read/write support and PICMG ekey support 2005-07-12 13:15:02 +00:00
89f6d591e0 added GetSelfTestResult defines 2005-07-12 13:13:47 +00:00
f9f0599908 added PICMG netfn\n ran lindent 2005-07-12 13:09:33 +00:00
c792f6e7e1 added SEL event definition for PICMG events 2005-07-12 12:42:02 +00:00
bce51c05f8 Added picmg fru data types 2005-07-12 12:37:23 +00:00
e0912fc6b7 Added initial PICMG command support 2005-07-12 12:36:47 +00:00
2c117c95ea added initial PICMG support
- added command support
 - added PICMG FRU data support
2005-07-12 12:36:00 +00:00
e7140ed0c8 added support for alternate devfs node location 2005-07-12 12:28:09 +00:00
6049aa0fe4 added support for channel and lun command line arguments 2005-07-12 12:25:29 +00:00
96876bb061 added support for built-in sdrs 2005-07-12 12:21:13 +00:00
4d2f9ebdc2 email address for Jon has changed 2005-07-11 20:14:00 +00:00
54dfc91b2b Extended the string list for Entity IDs, per the 2.0 spec's table 43-13. 2005-07-05 16:12:13 +00:00
86d54446e9 fix for freebsd 2005-06-28 21:14:51 +00:00
a7bcb2422e make rhel build i386 arch rpms on opteron when using 'make rpm' 2005-06-28 20:28:40 +00:00
4067bafa57 Added some support for the interpretation of OEM event messages (type 2 SEL
entries with with an event type in the OEM range).  For Newisys OEM SEL
entries, textual message descriptions are retrieved through a Newisys IPMI
OEM command.
include/ipmitool/ipmi_sel.h lib/ipmi_sel.c src/ipmievd.c CVS:
----------------------------------------------------------------------
2005-06-28 20:19:08 +00:00
624392f798 add check for tgetent to fix readline problems on RHEL4 2005-06-28 18:53:37 +00:00
ac2cc29ac0 remove / from string 2005-06-27 22:45:14 +00:00
87540ecf2a don't spin while waiting for 0 bytes in case BMC lies about how much data is in a FRU 2005-06-27 22:23:34 +00:00
6d77f698f2 allow SOL port to be sent in network byte order since some BMCs do this 2005-06-27 22:15:05 +00:00
083e6afc46 fix doc bug 2005-06-27 22:07:04 +00:00
384f9219ba move selftest results to its own command 2005-06-27 22:01:54 +00:00
fef402714f print binary data for i2c transactions 2005-06-25 17:33:35 +00:00
312b564091 A clarification (E347) in the IPMI v2 errata document (mark II) makes it
pretty clear that listing algorithms by cipher suite does not list all
algorithms, but lists supported algothms *grouped* by cipher suite.  Since
both views contain the same information, we will just support one in
ipmitool -- supported algorithms listed by cipher suite view.
2005-06-22 22:12:59 +00:00
a85bd201df work around readline 4.2 bug 2005-06-17 23:14:44 +00:00
e633524d34 fix freebsd compile problem 2005-06-17 23:12:53 +00:00
a892bb499a add configure option for specifying a distro tag for "make rpm" builds 2005-06-16 23:56:32 +00:00
836149f966 update changelog 2005-06-16 23:54:01 +00:00
694f92918f add support for entering netfn as a string for raw commands 2005-06-16 23:48:58 +00:00
1fe48e8a36 fix sdr printing of deassertion events and negative values for min/max 2005-06-16 23:47:15 +00:00
380f330e15 handle 0xcc response without error 2005-06-16 23:46:26 +00:00
fe38fb4e7b fix potential crash in cleanup code 2005-06-16 16:58:11 +00:00
ffd03bc964 two changes:
1. the IPMI spec says sessions are opened at USER level and must
be increased to desired privilege level.  This was not happening
for lanplus connections and causing problems with an OSA stack.

2. the 5ms delay between retries was not happening for SOL packets,
this is causing problems with a different implementation...
2005-06-16 16:53:01 +00:00
f9e30a894c typo 2005-06-16 16:50:28 +00:00
f733bcf2f1 decode cpu/dimm handling in sel if possible 2005-06-15 19:26:55 +00:00
51e906b7c6 Uploaded debian package into the Debian archive. 2005-06-05 09:01:32 +00:00
70cc60d8a4 add self-test results to chassis status output 2005-06-02 22:03:18 +00:00
c2c1204cb1 enable sdrcache on solaris 2005-06-02 22:02:41 +00:00
f87420b587 don't return error when user not supported 2005-06-02 22:01:36 +00:00
33cad9b907 In Get SEL Info, if the BMC returns a date of 0x00000000 of 0xffffffff,
print "Not available" instead of attempting to interpret the date.
2005-05-23 19:07:17 +00:00
b42902f880 Added the readraw and writeraw subcommands. These will allow the user
to save and view binary versions of the SEL.  The readraw subcommand is
being added to aid the Newisys troubleshooting facility, and the writeraw
subcommand is being added for parity.
2005-05-23 18:31:53 +00:00
8e77031a97 Added documentation for the readraw/writeraw subcommands. 2005-05-19 20:55:54 +00:00
b7962d85dc forgot one patch from sourceforge 2005-05-19 01:39:59 +00:00
36fefdabc3 update changelogs for 1.8.2 release 2005-05-18 23:51:18 +00:00
0ad17ece4a minor manpage update 2005-05-18 21:27:04 +00:00
990a9a4b6b fix display of binary encoded fru data 2005-05-18 07:14:15 +00:00
df7d0e6ee6 when caching sdrs from file leave room for trailing null to end description string 2005-05-17 22:55:25 +00:00
0f3c980b49 clear sensor desc before copying 2005-05-17 22:28:36 +00:00
8cfb4c0897 add helper define for max string length, allow default commands to receive options 2005-05-17 21:05:21 +00:00
650f12ab23 *** empty log message *** 2005-05-17 03:41:44 +00:00
fb0cc0187c don't print some event status fields 2005-05-16 23:59:39 +00:00
723b7c0614 export functions for use 2005-05-16 23:59:23 +00:00
bac5e21634 fix csv handling for 'sel elist' command 2005-05-15 17:47:13 +00:00
2ef302401e fix compile warnings with -Wall 2005-05-15 17:42:21 +00:00
cd174d8e73 don't stop looking when sensor is not found 2005-05-15 17:40:20 +00:00
718232945c add csv output support 2005-05-15 17:39:25 +00:00
fa3bb0960b broke fru lookups for 'sel get' command 2005-05-15 06:23:50 +00:00
b8a2890ace update manpage with new command help 2005-05-15 06:18:01 +00:00
5a7385f780 clean up output 2005-05-15 06:12:41 +00:00
9708c8326f add support for generating events based on sensor information 2005-05-15 05:59:36 +00:00
b1cf8c6a2b export function for other use 2005-05-15 05:57:35 +00:00
3af858eecf add 'sdr get' command, add hysteresis to sdr verbose output 2005-05-15 05:56:44 +00:00
f04b6d858f clean up output and shorten blink names 2005-05-15 05:55:09 +00:00
12c19f88ca add structure for PEMs 2005-05-15 04:53:39 +00:00
4385f3c403 *** empty log message *** 2005-05-15 04:52:18 +00:00
f598c42e2e fix str2val() 2005-05-15 04:51:02 +00:00
a567ac9426 fix handling of quotes in shell 2005-05-15 04:50:34 +00:00
2d0c486541 make sdr elist reporting consistent 2005-05-14 04:17:56 +00:00
1a4399a9eb conditional compile of ipmievd can go away 2005-05-14 03:37:29 +00:00
58c0fa890b minor fix for generic sdr display 2005-05-13 23:59:07 +00:00
06147e6a37 warm reset does not necessarily mean lost session 2005-05-13 17:09:27 +00:00
d559b1fa2d add man text for sel save command 2005-05-12 04:53:33 +00:00
bd30ca98db update manpages with help text for new commands 2005-05-12 04:47:51 +00:00
e5a6d23f9c clean up event messages 2005-05-12 04:24:16 +00:00
81aa0855f8 add -S option 2005-05-12 04:23:37 +00:00
281777996b add extended sel list functionality, ability to save SEL to a file 2005-05-12 04:23:07 +00:00
57c49ef9b8 lots of changes to SDR handling 2005-05-12 04:14:26 +00:00
adb40e53a1 add oem commands 2005-05-12 04:13:32 +00:00
db3da49158 break down GUID format 2005-05-12 04:12:40 +00:00
6f9b34313e fix invalid function prototyes 2005-05-11 05:56:47 +00:00
081baa7e24 print PEF actions 2005-05-11 05:55:20 +00:00
bbaf882dd1 add icts oem option 2005-05-11 05:55:05 +00:00
9e4ad72524 fix function prototype 2005-05-11 05:50:13 +00:00
ea0e9ca5fd add __max define 2005-05-11 05:49:41 +00:00
ace510828f add --enable-solaris-opt configure option to enable all command line options on solaris 2005-05-11 05:48:45 +00:00
6cc2c67671 add support for passing cmos clear bit to BIOS 2005-05-11 05:47:53 +00:00
d5d36e1941 add chassis power control vals 2005-05-11 05:46:40 +00:00
b65ec95257 remove unused variables 2005-05-11 05:45:17 +00:00
6b8d9243c2 add missing include 2005-05-11 05:44:53 +00:00
5c2cd09f6a fix function prototypes 2005-05-11 05:44:41 +00:00
e34c7eeb5c uninitialized variable 2005-05-11 05:44:23 +00:00
eb8653f02a add icts oem option, make bmc_rand not print with verbose mode 2005-05-11 04:42:51 +00:00
24a0b44a98 add noanswer flag to open interface 2005-05-11 04:42:06 +00:00
d69b8e8b7f fix typo in manpage 2005-05-03 15:54:47 +00:00
8b68086fdb change IPMI_CHANNEL_MEDIUM_IPMB define to not conflict with openipmi 2005-05-03 15:19:15 +00:00
35c6bb4a9d update manpages 2005-04-29 22:00:35 +00:00
928c500484 * New upstream release.
-  Fix FRU reading for large (>255 bytes) areas.
     -  Overhaul to ipmievd to support SEL polling in addition to OpenIPMI.
     -  Fix LAN parameter segfault when no Ciphers supported by
        BMC. (Closes: #306806)
     -  Fix IPMIv2 support on Intel v2 BMCs (use -o intelplus).
     -  Separate option parsing code from main ipmitool source file.
     -  Add raw I2C support with IPMI Master Read-Write command.
   * Correct the upstream URL in debian/changelog to the current one.
   * Suggest package openipmi. (Closes: #305629)
   * Add debian/watch file to detect new source versions.
2005-04-28 20:51:59 +00:00
2da00b9a47 * New upstream release.
-  Fix FRU reading for large (>255 bytes) areas.
     -  Overhaul to ipmievd to support SEL polling in addition to OpenIPMI.
     -  Fix LAN parameter segfault when no Ciphers supported by
        BMC. (Closes: #306806)
     -  Fix IPMIv2 support on Intel v2 BMCs (use -o intelplus).
     -  Separate option parsing code from main ipmitool source file.
     -  Add raw I2C support with IPMI Master Read-Write command.
   * Correct the upstream URL in debian/changelog to the current one.
   * Suggest package openipmi. (Closes: #305629)
2005-04-28 20:45:28 +00:00
04802db0e0 Correct the upstream URL in debian/changelog to the current one. 2005-04-28 20:43:53 +00:00
85d612fa35 command list missing from shell help 2005-04-28 15:58:46 +00:00
1340786bda fix handling of sel when it is cleared 2005-04-27 22:39:15 +00:00
30eec7d0ac only decode sensor-specific states 2005-04-22 19:53:27 +00:00
5298b1ca71 fix memory leaks, optimize payload allocator to only allocate what is needed instead of max amount 2005-04-22 19:52:01 +00:00
a292d94239 fix handling of sensors that are read correctly 2005-04-22 05:07:17 +00:00
26557547b4 typos 2005-04-21 04:21:50 +00:00
2c2437239d fix chassis power status exit code 2005-04-21 04:13:55 +00:00
7b3fac2071 fix chassis power status command 2005-04-21 03:30:55 +00:00
763abe4889 add sys/poll header for internal openipmi compiles 2005-04-21 01:13:01 +00:00
2a574a3e8b update changelogs for release,
add readme for debian packages that points to howto by Tim Small
2005-04-21 00:08:15 +00:00
f108b55d13 don't display open command for ipmievd when not available 2005-04-20 23:38:16 +00:00
13659fb466 add ipmievd to solaris packages 2005-04-20 23:27:49 +00:00
412798482c fix segfault from stupid error 2005-04-20 23:10:30 +00:00
90448837ec add ability to configure session retry and timeout settings,
add chassis power status command with return value indicating status
2005-04-20 23:04:00 +00:00
fecfc09c8b update version to 1.8.2, ipmievd can now build and work on non-linux systems 2005-04-20 22:49:25 +00:00
820d9e6bb3 massive overhaul to ipmievd to support both openipmi event message buffer and manual SEL polling 2005-04-20 22:48:49 +00:00
251de396a1 ipmi_intf_print takes argument listing supported interfaces 2005-04-20 22:46:52 +00:00
774c74a64c fix fru decoding for large areas, was overflowing 8bit counter 2005-04-20 22:42:11 +00:00
c7c5b2de37 add daemonize function to helper library 2005-04-20 22:40:53 +00:00
762f6fff1c ipmi_intf_print takes optional list of 'supported' interfaces to display 2005-04-20 21:43:02 +00:00
4ea12d4308 add ipmi_main.[ch] to the build system 2005-04-20 21:41:58 +00:00
ce01d13e98 move option parsing and command handling to its own file for reuse 2005-04-20 21:05:45 +00:00
1c4f38bba8 add rawi2c master read/write command 2005-04-20 21:03:33 +00:00
b2c96c3a1f add noanswer flag, and ipmi_cmd structures 2005-04-20 20:52:30 +00:00
4c99a6f676 intelplus mode does not try for highest priv based on algorithms 2005-04-20 20:48:47 +00:00
78049bf3b7 add system firwmware sensor-specific bits, add function to get sensor type based on event code and offset 2005-04-20 20:47:05 +00:00
6052a2b57a add sdr_cache function, fix Get SDR Header to handle cancelled reservation 2005-04-20 20:44:59 +00:00
392454c646 handle parameter out of range error without returning error code, fix segfault when no cipher suites defined 2005-04-20 20:36:01 +00:00
805835ca69 Properly close a session if our set session priv level command failed.
By this time we have activated successfully.
2005-04-08 21:37:33 +00:00
c86c21e734 Added missing val2str(rsp->ccode, completion_code_vals) for format argument. 2005-04-08 19:19:04 +00:00
897b3c5a46 Changelog for 1.8.1-1 debian release. 2005-04-06 23:19:46 +00:00
4e93bf01ed missing checkin seems to have disappeared: up to 1.8.1 2005-04-06 22:44:01 +00:00
9573ee3eed add linux/compile.h for 2.6 compiles 2005-04-06 20:51:02 +00:00
ef4e6f3dad ipmievd installs in /usr/sbin 2005-04-06 20:33:29 +00:00
3d30271e73 prefix with dist_ so they get included with make dist 2005-04-04 22:13:48 +00:00
c39a8026da avoid possible redefine 2005-04-04 01:15:20 +00:00
20a4a2f950 updates to debian builds from Petter Reinholdtsen 2005-04-04 01:09:50 +00:00
55ac08dc49 always remove old device file in case we get new dynamic major assigned from kernel 2005-04-03 22:45:56 +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
88 changed files with 17249 additions and 3670 deletions

View File

@ -1,3 +1,41 @@
version 1.8.3
* Add support for 'sel readraw' and 'sel writeraw' commands.
* Add support for entering NetFn as a string for RAW commands.
* Add support for appending distro tag to integrated RPM builds.
* Fix LAN parameter printing to handle Invalid Data Field response
without errors.
* Add 5ms delay to IPMIv2 SOL retry packets
* IPMIv2 interface will now correctly set session privilege level
to requested level after session is opened.
version 1.8.2 (released May 18 2005)
* Fix FRU reading for large (>255 bytes) areas.
* Overhaul to ipmievd to support SEL polling in addition to OpenIPMI.
* Fix LAN parameter segfault when no Ciphers supported by BMC.
* Fix IPMIv2 support on Intel v2 BMCs (use -o intelplus).
* Separate option parsing code from main ipmitool source file.
* Add raw I2C support with IPMI Master Read-Write command.
* Add support for new 'sdr elist' extended output format.
* Add support for listing sensors by type with 'sdr type' command.
* Add support for new 'sel elist' extended output format that
cross-references events with sensors.
* Add support for sending dynamically generated platform events
based on existing sensor information.
* New '-S' argument to read local SDR cache created with 'sdr dump'.
* Updated manpage for ipmitool and ipmievd.
version 1.8.1
* ipmievd installs in /usr/sbin
version 1.8.0
* Fix IPMIv2.0 issues
* Fix chassis boot parameter support
* Add support for linear sensors
version 1.7.1
* Update bmc plugin to work with new Solaris bmc driver (new ioctl
for interface detection and new STREAMS message-based interface)
version 1.7.0 version 1.7.0
* Propogate errors correctly so exit status will be useful * Propogate errors correctly so exit status will be useful
* More consistent display of errors including completion code text * More consistent display of errors including completion code text

View File

@ -3,7 +3,7 @@ dnl autoconf for ipmitool
dnl dnl
AC_INIT([src/ipmitool.c]) AC_INIT([src/ipmitool.c])
AC_CANONICAL_SYSTEM AC_CANONICAL_SYSTEM
AM_INIT_AUTOMAKE([ipmitool], [1.7.0]) AM_INIT_AUTOMAKE([ipmitool], [1.8.5])
AM_CONFIG_HEADER(config.h) AM_CONFIG_HEADER(config.h)
AC_CONFIG_SRCDIR([src/ipmitool.c]) AC_CONFIG_SRCDIR([src/ipmitool.c])
AC_PREREQ(2.50) AC_PREREQ(2.50)
@ -18,7 +18,7 @@ AC_CHECK_PROG([RPMBUILD], [rpmbuild], [rpmbuild], [rpm])
AC_CHECK_PROG([SED], [sed], [sed]) AC_CHECK_PROG([SED], [sed], [sed])
AC_HEADER_STDC AC_HEADER_STDC
AC_CHECK_HEADERS([stdlib.h string.h sys/ioctl.h sys/stat.h unistd.h]) AC_CHECK_HEADERS([stdlib.h string.h sys/ioctl.h sys/stat.h unistd.h paths.h termios.h])
AC_CHECK_HEADERS([arpa/inet.h fcntl.h netdb.h netinet/in.h sys/socket.h]) AC_CHECK_HEADERS([arpa/inet.h fcntl.h netdb.h netinet/in.h sys/socket.h])
AC_CHECK_HEADERS([sys/byteorder.h byteswap.h]) AC_CHECK_HEADERS([sys/byteorder.h byteswap.h])
@ -51,6 +51,8 @@ if test "x$exec_prefix" = "xNONE"; then
exec_prefix="$prefix" exec_prefix="$prefix"
fi fi
enable_all_options=yes
dnl set some things so we build with GNU tools on Solaris dnl set some things so we build with GNU tools on Solaris
case "$host_os" in case "$host_os" in
solaris*) solaris*)
@ -58,11 +60,35 @@ solaris*)
STRIP=gstrip STRIP=gstrip
LD=gld LD=gld
AR=gar AR=gar
# openssl libs are in /usr/sfw/lib on solaris 10
LIBS="$LIBS -R/usr/sfw/lib"
# disable the linux-specific interfaces # disable the linux-specific interfaces
# 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 enable_intf_bmc=yes
fi
enable_intf_imb=no enable_intf_imb=no
enable_intf_open=no enable_intf_open=no
enable_ipmievd=no enable_intf_lipmi=no
enable_ipmishell=no
enable_all_options=no
;;
*cygwin*)
# disable the linux and solaris-specific interfaces
enable_intf_imb=no
enable_intf_open=no
enable_intf_lipmi=no
enable_intf_bmc=no
enable_ipmishell=no
;;
*darwin*)
# disable the linux and solaris-specific interfaces
enable_intf_imb=no
enable_intf_open=no
enable_intf_lipmi=no
enable_intf_bmc=no
enable_ipmishell=no enable_ipmishell=no
;; ;;
esac esac
@ -72,6 +98,15 @@ AC_SUBST(OS, $host_os)
AC_SUBST(PSTAMP, $host) AC_SUBST(PSTAMP, $host)
AC_SUBST(BASEDIR, $prefix) AC_SUBST(BASEDIR, $prefix)
dnl allow solaris builds to include all options
AC_ARG_ENABLE([solaris-opt],
[AC_HELP_STRING([--enable-solaris-opt],
[enable all options for Solaris [default=no]])],
[], [enable_solaris_opt=no])
if test "x$enable_all_options" = "xyes" || test "x$enable_solaris_opt" = "xyes"; then
AC_DEFINE(ENABLE_ALL_OPTIONS, [1], [Define to 1 to enable all command line options.])
fi
dnl check for OpenSSL functionality dnl check for OpenSSL functionality
AC_ARG_ENABLE([internal-md5], AC_ARG_ENABLE([internal-md5],
[AC_HELP_STRING([--enable-internal-md5], [AC_HELP_STRING([--enable-internal-md5],
@ -159,10 +194,16 @@ AC_CHECK_HEADER([linux/ipmi.h],
[Define to 1 if you have the <linux/ipmi.h> header file.])], [Define to 1 if you have the <linux/ipmi.h> header file.])],
[echo "** Unable to find OpenIPMI header files. Using internal version."]) [echo "** Unable to find OpenIPMI header files. Using internal version."])
dnl set RPM distro tag for use in RPM name
AC_ARG_WITH([rpm-distro],
[AC_HELP_STRING([--with-rpm-distro=DISTRO],
[set Linux distribution tag for use in RPM version string])],
[AC_SUBST(DISTRO, $with_rpm_distro)])
dnl enable Linux OpenIPMI interface dnl enable Linux OpenIPMI interface
AC_ARG_ENABLE([intf-open], AC_ARG_ENABLE([intf-open],
[AC_HELP_STRING([--enable-intf-open], [AC_HELP_STRING([--enable-intf-open],
[enable Linux OpenIPMI interface [default=yes]])], [enable Linux OpenIPMI interface [default=auto]])],
[], [enable_intf_open=yes]) [], [enable_intf_open=yes])
if test "x$enable_intf_open" = "xstatic" || test "x$enable_intf_open" = "xplugin"; then if test "x$enable_intf_open" = "xstatic" || test "x$enable_intf_open" = "xplugin"; then
enable_intf_open=yes enable_intf_open=yes
@ -177,7 +218,7 @@ fi
dnl enable Intel IMB interface dnl enable Intel IMB interface
AC_ARG_ENABLE([intf-imb], AC_ARG_ENABLE([intf-imb],
[AC_HELP_STRING([--enable-intf-imb], [AC_HELP_STRING([--enable-intf-imb],
[enable Intel IMB driver interface [default=yes]])], [enable Intel IMB driver interface [default=auto]])],
[], [enable_intf_imb=yes]) [], [enable_intf_imb=yes])
if test "x$enable_intf_imb" = "xstatic" || test "x$enable_intf_imb" = "xplugin"; then if test "x$enable_intf_imb" = "xstatic" || test "x$enable_intf_imb" = "xplugin"; then
enable_intf_imb=yes enable_intf_imb=yes
@ -212,7 +253,7 @@ fi
dnl enable Solaris BMC interface dnl enable Solaris BMC interface
AC_ARG_ENABLE([intf-bmc], AC_ARG_ENABLE([intf-bmc],
[AC_HELP_STRING([--enable-intf-bmc], [AC_HELP_STRING([--enable-intf-bmc],
[enable Solaris 10 x86 IPMI interface [default=no]])],, [enable Solaris 10 x86 IPMI interface [default=auto]])],,
[enable_intf_bmc=no]) [enable_intf_bmc=no])
if test "x$enable_intf_bmc" = "xstatic" || test "x$enable_intf_bmc" = "xplugin"; then if test "x$enable_intf_bmc" = "xstatic" || test "x$enable_intf_bmc" = "xplugin"; then
enable_intf_bmc=yes enable_intf_bmc=yes
@ -232,29 +273,20 @@ AC_ARG_ENABLE([ipmishell],
[enable IPMI shell interface [default=yes]])], [enable IPMI shell interface [default=yes]])],
[], [enable_ipmishell=yes]) [], [enable_ipmishell=yes])
if test "x$enable_ipmishell" = "xyes"; then if test "x$enable_ipmishell" = "xyes"; then
AC_SEARCH_LIBS([tgetent], [readline ncurses curses termcap])
AC_SEARCH_LIBS([initscr], [curses ncurses], [have_curses=yes]) AC_SEARCH_LIBS([initscr], [curses ncurses], [have_curses=yes])
AC_SEARCH_LIBS([readline], [readline], [have_readline=yes]) AC_SEARCH_LIBS([readline], [readline edit], [have_readline=yes])
if test "x$have_curses" = "xyes" && test "x$have_readline" = "xyes"; then if test "x$have_curses" = "xyes" && test "x$have_readline" = "xyes"; then
AC_DEFINE(HAVE_READLINE, [1], [Define to 1 if readline present.]) AC_DEFINE(HAVE_READLINE, [1], [Define to 1 if readline present.])
fi fi
fi fi
dnl enable IPMI Event Daemon
AC_ARG_ENABLE([ipmievd],
[AC_HELP_STRING([--enable-ipmievd],
[enable IPMI Event daemon [default=yes]])],
[], [enable_ipmievd=yes])
AM_CONDITIONAL(IPMIEVD, [test "x$enable_ipmievd" = "xyes"])
if test "x$enable_ipmievd" = "xyes"; then
AC_SUBST(IPMIEVD_BIN, [ipmievd])
fi
dnl Enable -Wall -Werror dnl Enable -Wall -Werror
AC_ARG_ENABLE([buildcheck], AC_ARG_ENABLE([buildcheck],
[AC_HELP_STRING([--enable-buildcheck], [AC_HELP_STRING([--enable-buildcheck],
[enable -Wall -Werror for build testing [default=no]])], [enable -Wall -Werror for build testing [default=no]])],
[if test "x$enable_buildcheck" != "xno"; then [if test "x$enable_buildcheck" != "xno"; then
CFLAGS="$CFLAGS -Wall -Werror" CFLAGS="$CFLAGS -Wall -Werror -Wpointer-arith -Wstrict-prototypes"
fi], []) fi], [])
AC_SUBST(CFLAGS) AC_SUBST(CFLAGS)
@ -266,6 +298,7 @@ AC_CONFIG_FILES([Makefile
control/Makefile control/Makefile
control/pkginfo control/pkginfo
control/prototype control/prototype
control/rpmmacros
control/ipmitool.spec control/ipmitool.spec
lib/Makefile lib/Makefile
include/Makefile include/Makefile
@ -293,6 +326,6 @@ AC_MSG_RESULT([ bmc : $enable_intf_bmc])
AC_MSG_RESULT([ lipmi : $enable_intf_lipmi]) AC_MSG_RESULT([ lipmi : $enable_intf_lipmi])
AC_MSG_RESULT([]) AC_MSG_RESULT([])
AC_MSG_RESULT([Extra tools]) AC_MSG_RESULT([Extra tools])
AC_MSG_RESULT([ ipmievd : $enable_ipmievd]) AC_MSG_RESULT([ ipmievd : yes])
AC_MSG_RESULT([]) AC_MSG_RESULT([])

View File

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

View File

@ -48,6 +48,12 @@ start() {
# this failure. # this failure.
grep -q ipmidev /proc/devices || RETVAL=1 grep -q ipmidev /proc/devices || RETVAL=1
# remove old device file always
# in case ipmi gets assigned new dynamic major number from kernel
if [ -c /dev/ipmi0 ]; then
rm -f /dev/ipmi0
fi
# Check if the device file exists and create if not. # Check if the device file exists and create if not.
if [ ! -c /dev/ipmi0 ] && [ $RETVAL -eq 0 ] if [ ! -c /dev/ipmi0 ] && [ $RETVAL -eq 0 ]
then then

View File

@ -34,8 +34,8 @@
MAINTAINERCLEANFILES = Makefile.in MAINTAINERCLEANFILES = Makefile.in
EXTRA_DIST = pkginfo.in prototype.in ipmitool.spec.in \ EXTRA_DIST = pkginfo.in prototype.in \
rpmrc rpmmacros ipmitool.spec.in rpmmacros.in rpmrc
dist-hook: pkginfo prototype dist-hook: pkginfo prototype rpmmacros

View File

@ -32,8 +32,10 @@ fi
%build %build
./configure --with-kerneldir \ ./configure --with-kerneldir \
--with-rpm-distro=@DISTRO@ \
--prefix=%{_prefix} \ --prefix=%{_prefix} \
--bindir=%{_bindir} \ --bindir=%{_bindir} \
--sbindir=%{_sbindir} \
--datadir=%{_datadir} \ --datadir=%{_datadir} \
--includedir=%{_includedir} \ --includedir=%{_includedir} \
--libdir=%{_libdir} \ --libdir=%{_libdir} \
@ -53,11 +55,65 @@ rm -rf $RPM_BUILD_DIR/ipmitool-@VERSION@
%files %files
%defattr(-,root,root) %defattr(-,root,root)
%{_bindir}/* %{_bindir}/*
%{_sbindir}/*
%{_datadir}/ipmitool/* %{_datadir}/ipmitool/*
%doc %{_mandir}/man1/* %doc %{_mandir}/man1/*
%doc %{_mandir}/man8/*
%doc %{_datadir}/doc/ipmitool/* %doc %{_datadir}/doc/ipmitool/*
%changelog %changelog
* Sat Jan 14, 2006 <duncan@iceblink.org> 1.8.5-1
- Raise privilege level after creating IPMIv2 session
- Add support for settable SOL escape character with -e option
- Add support for Kg BMC key for IPMIv2 authentication with -k option
- Add support for Tyan IPMIv1.5 SOL with tsol command
- Add support for PICMG devices
- Add support for OEM SEL event parsing
- Add support for command bridging over lan and lanplus interfaces
- New 'chassis selftest' command
- Many bufxies and patches from contributors
* Wed May 18 2005 <duncan@iceblink.org> 1.8.2-1
- Fix FRU reading for large (>255 bytes) areas.
- Overhaul to ipmievd to support SEL polling in addition to OpenIPMI.
- Fix LAN parameter segfault when no Ciphers supported by BMC.
- Fix IPMIv2 support on Intel v2 BMCs (use -o intelplus).
- Separate option parsing code from main ipmitool source file.
- Add raw I2C support with IPMI Master Read-Write command.
- Add support for new 'sdr elist' extended output format.
- Add support for listing sensors by type with 'sdr type' command.
- Add support for new 'sel elist' extended output format that
cross-references events with sensors.
- Add support for sending dynamically generated platform events
based on existing sensor information.
- New '-S' argument to read local SDR cache created with 'sdr dump'.
- Updated manpage for ipmitool and ipmievd.
* Wed Apr 06 2005 <duncan@iceblink.org> 1.8.1-1
- Install ipmievd into /usr/sbin
* Wed Mar 16 2005 <duncan@iceblink.org> 1.8.0-1
- Fix IPMIv2.0 issues
- Fix chassis boot parameter support
- Add support for linear sensors
- Update bmc plugin to work with new Solaris bmc driver (new ioctl
for interface detection and new STREAMS message-based interface)
* Tue Jan 18 2005 <duncan@iceblink.org> 1.7.0-1
- Propogate errors correctly so exit status will be useful
- More consistent display of errors including completion code text
- Errors and debug is send to stderr now
- New "sel get" command that will print details about SEL entry
and corresponding SDR records as well as FRUs via entity association
- Improved event generator, now supports reading events from text file
- New "-o oemtype" option for specifying OEM boards
exsting types are "supermicro" and "intelwv2"
- New PEF subsystem from Tim Murphy at Dell
- New "bmc" plugin for Solaris 10 x86
- Many bugfixes and contributed patches
- Support for Supermicro BMC OEM authentication method
- Fix minor problem with LAN parameter setting
* Wed Aug 18 2004 <duncan@iceblink.org> 1.6.0-1 * Wed Aug 18 2004 <duncan@iceblink.org> 1.6.0-1
- Add a README - Add a README
- Add support for IPMIv2 and Serial-over-LAN from Newisys - Add support for IPMIv2 and Serial-over-LAN from Newisys

View File

@ -4,7 +4,7 @@ ARCH="@ARCH@"
VERSION="@VERSION@" VERSION="@VERSION@"
CATEGORY="system" CATEGORY="system"
VENDOR="Duncan Laurie" VENDOR="Duncan Laurie"
EMAIL="duncan@sun.com" EMAIL="duncan@iceblink.org"
PSTAMP="@PSTAMP@" PSTAMP="@PSTAMP@"
BASEDIR="@BASEDIR@" BASEDIR="@BASEDIR@"
CLASSES="none" CLASSES="none"

View File

@ -1,7 +1,12 @@
i pkginfo i pkginfo
d none bin ? ? ? d none bin ? ? ?
f none bin/@PACKAGE@=../src/@PACKAGE@ 0755 root bin f none bin/@PACKAGE@=../src/@PACKAGE@ 0755 root bin
d none sbin ? ? ?
f none sbin/ipmievd=../src/ipmievd 0755 root bin
d none share ? ? ? d none share ? ? ?
d none share/man ? ? ? d none share/man ? ? ?
d none share/man/man1 ? ? ? d none share/man/man1 ? ? ?
f none share/man/man1/@PACKAGE@.1=../doc/@PACKAGE@.1 0644 root bin f none share/man/man1/@PACKAGE@.1=../doc/@PACKAGE@.1 0644 root bin
d none share/man/man8 ? ? ?
f none share/man/man8/ipmievd.8=../doc/ipmievd.8 0644 root bin

View File

@ -6,6 +6,7 @@
%_buildroot %{_topdir}/%{_tmppath}/%{name}-%{version}-root %_buildroot %{_topdir}/%{_tmppath}/%{name}-%{version}-root
%_rpmdir %{_topdir}/RPMS %_rpmdir %{_topdir}/RPMS
%_srcrpmdir %{_topdir}/SRPMS %_srcrpmdir %{_topdir}/SRPMS
%_distro @DISTRO@
%_rpmfilename %%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm %_rpmfilename %%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm
%packager duncan@iceblink.org %packager duncan@iceblink.org
%distribution Sourceforge Build %distribution Sourceforge Build

View File

@ -1 +1,8 @@
macrofiles: /usr/lib/rpm/macros:/usr/lib/rpm/%{_target}/macros:/etc/rpm/macros.specspo:/etc/rpm/macros:/etc/rpm/%{_target}/macros:%(echo $CONFIGDIR)/rpmmacros macrofiles: /usr/lib/rpm/macros:/usr/lib/rpm/%{_target}/macros:/etc/rpm/macros.specspo:/etc/rpm/macros:/etc/rpm/%{_target}/macros:%(echo $CONFIGDIR)/rpmmacros
buildarchtranslate: athlon: i386
buildarchtranslate: i686: i386
buildarchtranslate: i586: i386
buildarchtranslate: i486: i386
buildarchtranslate: i386: i386

View File

@ -0,0 +1,5 @@
For more information about setting up your Debian system with IPMI
please see the excellent howto by Tim Small:
http://buttersideup.com/docs/howto/IPMI_on_Debian.html

View File

@ -1,3 +1,68 @@
ipmitool (1.8.2-1) unstable; urgency=low
* New upstream release.
- Fix FRU reading for large (>255 bytes) areas.
- Overhaul to ipmievd to support SEL polling in addition to OpenIPMI.
- Fix LAN parameter segfault when no Ciphers supported by
BMC. (Closes: #306806)
- Fix IPMIv2 support on Intel v2 BMCs (use -o intelplus).
- Separate option parsing code from main ipmitool source file.
- Add raw I2C support with IPMI Master Read-Write command.
- Add support for new 'sdr elist' extended output format.
- Add support for listing sensors by type with 'sdr type' command.
- Add support for new 'sel elist' extended output format that
cross-references events with sensors.
- Add support for sending dynamically generated platform events
based on existing sensor information.
- New '-S' argument to read local SDR cache created with 'sdr dump'.
- Updated manpage for ipmitool and ipmievd. (Closes: #306894)
* Correct the upstream URL in debian/changelog to the current one.
* Suggest package openipmi. (Closes: #305629)
* Add debian/watch file to detect new source versions.
-- Petter Reinholdtsen <pere@debian.org> Sun, 5 Jun 2005 10:29:18 +0200
ipmitool (1.8.1-1) unstable; urgency=low
* New upstream release.
* Install ipmievd into /usr/sbin/.
-- Petter Reinholdtsen <pere@debian.org> Thu, 7 Apr 2005 01:18:44 +0200
ipmitool (1.8.0-1) unstable; urgency=low
* Initial upload into Debian, based on the upstream build
rules. (Closes: #299924)
* Convert debian/changelog to UTF-8.
* Change section from 'contrib' to 'utils'.
* Build-depend on debhelper (>> 4.0.0) to match the rules file.
* Set Standards-version to 3.6.1.
* Make sure binary dependency is properly generated.
* Add long description, copied from the project README.
* Drop useless provides 'ipmitool', as the package is called 'ipmitool'.
* Don't install the COPYING file, as the license text already is
included in debian/copyright.
* Remove unused parts of the rules file.
* Correct clean target in rules file, to use 'distclean' and remove
configure-stamp not bogus config-stamp.
-- Petter Reinholdtsen <pere@debian.org> Sun, 3 Apr 2005 20:52:02 +0200
ipmitool (1.8.0) unstable; urgency=low
* Fix IPMIv2.0 issues
* Fix chassis boot parameter support
* Add support for linear sensors
-- Duncan Laurie <duncan@iceblink.org> Wed, Mar 16 2005 17:08:12 -0700
ipmitool (1.7.1) unstable; urgency=low
* Update bmc plugin to work with new Solaris bmc driver (new ioctl
for interface detection and new STREAMS message-based interface).
-- Seth Goldberg <sethmeisterg@hotmail.com> Mon, Mar 7 2005 18:03:00 -0800
ipmitool (1.7.0) unstable; urgency=low ipmitool (1.7.0) unstable; urgency=low
* Propogate errors correctly so exit status will be useful * Propogate errors correctly so exit status will be useful
@ -55,7 +120,7 @@ ipmitool (1.5.9) unstable; urgency=low
* Add configure option for changing binary to ipmiadm for Solaris * Add configure option for changing binary to ipmiadm for Solaris
* Fix compile problem on Solaris 8 * Fix compile problem on Solaris 8
-- Duncan Laurie <duncan@sun.com> Sat, 27 Mar 2004 00:11:37 -0700 -- Duncan Laurie <duncan@iceblink.org> Sat, 27 Mar 2004 00:11:37 -0700
ipmitool (1.5.8) unstable; urgency=low ipmitool (1.5.8) unstable; urgency=low
@ -69,7 +134,7 @@ ipmitool (1.5.8) unstable; urgency=low
* Add support for Linux kernel panic messages in SEL output * Add support for Linux kernel panic messages in SEL output
* Add support for type 3 SDR records * Add support for type 3 SDR records
-- Duncan Laurie <duncan@sun.com> Tue, 27 Jan 2004 16:23:25 -0700 -- Duncan Laurie <duncan@iceblink.org> Tue, 27 Jan 2004 16:23:25 -0700
ipmitool (1.5.7) unstable; urgency=low ipmitool (1.5.7) unstable; urgency=low
@ -78,49 +143,49 @@ ipmitool (1.5.7) unstable; urgency=low
* better handling of SDR printing * better handling of SDR printing
* contrib scripts for creating rrdtool graphs * contrib scripts for creating rrdtool graphs
-- Duncan Laurie <duncan@sun.com> Mon, 5 Jan 2004 17:29:50 -0700 -- Duncan Laurie <duncan@iceblink.org> Mon, 5 Jan 2004 17:29:50 -0700
ipmitool (1.5.6) unstable; urgency=low ipmitool (1.5.6) unstable; urgency=low
* Fix SEL event decoding for generic events * Fix SEL event decoding for generic events
* Handle empty SEL gracefully when doing "sel list" * Handle empty SEL gracefully when doing "sel list"
* Fix sdr handling of sensors that do not return a reading * Fix sdr handling of sensors that do not return a reading
* Fix for CSV display of sensor readings/units from Fredrik <EFBFBD>hrn * Fix for CSV display of sensor readings/units from Fredrik Öhrn
-- Duncan Laurie <duncan@sun.com> Thu, 4 Dec 2003 14:47:19 -0700 -- Duncan Laurie <duncan@iceblink.org> Thu, 4 Dec 2003 14:47:19 -0700
ipmitool (1.5.5) unstable; urgency=low ipmitool (1.5.5) unstable; urgency=low
* Add -U option for setting LAN username * Add -U option for setting LAN username
* Fix -v usage for plugin interfaces * Fix -v usage for plugin interfaces
-- Duncan Laurie <duncan@sun.com> Tue, 25 Nov 2003 15:10:48 -0700 -- Duncan Laurie <duncan@iceblink.org> Tue, 25 Nov 2003 15:10:48 -0700
ipmitool (1.5.4) unstable; urgency=low ipmitool (1.5.4) unstable; urgency=low
* Put interface plugin API into library * Put interface plugin API into library
* Fix ipmievd * Fix ipmievd
-- Duncan Laurie <duncan@sun.com> Fri, 14 Nov 2003 15:16:34 -0700 -- Duncan Laurie <duncan@iceblink.org> Fri, 14 Nov 2003 15:16:34 -0700
ipmitool (1.5.3) unstable; urgency=low ipmitool (1.5.3) unstable; urgency=low
* Add -g option to work with grizzly bmc * Add -g option to work with grizzly bmc
-- Duncan Laurie <duncan@sun.com> Mon, 3 Nov 2003 18:04:07 -0700 -- Duncan Laurie <duncan@iceblink.org> Mon, 3 Nov 2003 18:04:07 -0700
ipmitool (1.5.2) unstable; urgency=low ipmitool (1.5.2) unstable; urgency=low
* add support for setting gratuitous arp interval * add support for setting gratuitous arp interval
-- Duncan Laurie <duncan@sun.com> Fri, 24 Oct 2003 11:00:00 -0700 -- Duncan Laurie <duncan@iceblink.org> Fri, 24 Oct 2003 11:00:00 -0700
ipmitool (1.5.1) unstable; urgency=low ipmitool (1.5.1) unstable; urgency=low
* better SEL support * better SEL support
* fix display bug in SDR list * fix display bug in SDR list
-- Duncan Laurie <duncan@sun.com> Wed, 8 Oct 2003 17:28:51 -0700 -- Duncan Laurie <duncan@iceblink.org> Wed, 8 Oct 2003 17:28:51 -0700
ipmitool (1.5.0) unstable; urgency=low ipmitool (1.5.0) unstable; urgency=low
@ -128,24 +193,24 @@ ipmitool (1.5.0) unstable; urgency=low
* add Intel IMB driver support * add Intel IMB driver support
* use autoconf/automake/libtool * use autoconf/automake/libtool
-- Duncan Laurie <duncan@sun.com> Fri, 5 Sep 2003 11:57:32 -0700 -- Duncan Laurie <duncan@iceblink.org> Fri, 5 Sep 2003 11:57:32 -0700
ipmitool (1.2-1) unstable; urgency=low ipmitool (1.2-1) unstable; urgency=low
* New command line option parsing * New command line option parsing
* More chassis commands supported * More chassis commands supported
-- Duncan Laurie <duncan@sun.com> Wed, 2 Apr 2003 17:44:17 -0700 -- Duncan Laurie <duncan@iceblink.org> Wed, 2 Apr 2003 17:44:17 -0700
ipmitool (1.1-1) unstable; urgency=low ipmitool (1.1-1) unstable; urgency=low
* Minor fixes. * Minor fixes.
-- Duncan Laurie <duncan@sun.com> Tue, 1 Apr 2003 14:31:10 -0700 -- Duncan Laurie <duncan@iceblink.org> Tue, 1 Apr 2003 14:31:10 -0700
ipmitool (1.0-1) unstable; urgency=low ipmitool (1.0-1) unstable; urgency=low
* Initial Release. * Initial Release.
-- Duncan Laurie <duncan@sun.com> Sun, 30 Mar 2003 21:30:46 -0700 -- Duncan Laurie <duncan@iceblink.org> Sun, 30 Mar 2003 21:30:46 -0700

View File

@ -1,12 +1,28 @@
Source: ipmitool Source: ipmitool
Section: contrib Section: utils
Priority: optional Priority: optional
Maintainer: Duncan Laurie <duncan@iceblink.org> Maintainer: Petter Reinholdtsen <pere@debian.org>
Build-Depends: debhelper (>> 3.0.0) Uploaders: Duncan Laurie <duncan@iceblink.org>
Standards-Version: 3.5.8 Build-Depends: debhelper (>> 4.0.0),
Standards-Version: 3.6.1
Package: ipmitool Package: ipmitool
Architecture: i386 amd64 Architecture: i386 amd64
Provides: ipmitool Depends: ${shlibs:Depends}
Description: Utility for IPMI control with kernel driver or LAN interface Suggest: openipmi
Description: utility for IPMI control with kernel driver or LAN interface
A utility for managing and configuring devices that support the
Intelligent Platform Management Interface. IPMI is an open standard
for monitoring, logging, recovery, inventory, and control of hardware
that is implemented independent of the main CPU, BIOS, and OS. The
service processor (or Baseboard Management Controller, BMC) is the
brain behind platform management and its primary purpose is to handle
the autonomous sensor monitoring and event logging features.
.
The ipmitool program provides a simple command-line interface to this
BMC. It features the ability to read the sensor data repository
(SDR) and print sensor values, display the contents of the System
Event Log (SEL), print Field Replaceable Unit (FRU) inventory
information, read and set LAN configuration parameters, and perform
remote chassis power control.

View File

@ -1,6 +1,9 @@
ipmitool This package was debianized by Duncan Laurie before
Duncan Laurie <duncan@sun.com> 2003-11-18 17:55:21 +0100.
http://www.iceblink.org/ipmitool/
It was downloaded from <URL:http://ipmitool.sourceforge.net/>
Upstream Author: Duncan Laurie <duncan@iceblink.org>
Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
@ -35,4 +38,3 @@ EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
You acknowledge that this software is not designed or intended for use You acknowledge that this software is not designed or intended for use
in the design, construction, operation or maintenance of any nuclear in the design, construction, operation or maintenance of any nuclear
facility. facility.

View File

@ -1,3 +1,4 @@
usr/bin usr/bin
usr/sbin
usr/share/ipmitool usr/share/ipmitool
usr/share/doc/ipmitool usr/share/doc/ipmitool

View File

@ -1,4 +1,2 @@
README README
COPYING
AUTHORS AUTHORS
ChangeLog

View File

@ -41,10 +41,10 @@ build-indep-stamp: configure-stamp
clean: clean:
dh_testdir dh_testdir
dh_testroot dh_testroot
rm -f build-arch-stamp build-indep-stamp config-stamp rm -f build-arch-stamp build-indep-stamp configure-stamp
# Add here commands to clean up after the build process. # Add here commands to clean up after the build process.
-$(MAKE) clean -$(MAKE) distclean
dh_clean dh_clean
@ -71,6 +71,17 @@ install-arch:
# debian/tmp. # debian/tmp.
$(MAKE) install DESTDIR=$(CURDIR)/debian/ipmitool $(MAKE) install DESTDIR=$(CURDIR)/debian/ipmitool
# No need to have two copies of the license text in the package.
$(RM) $(CURDIR)/debian/ipmitool/usr/share/doc/ipmitool/COPYING
# Move upstream changelog to correct filename.
mv $(CURDIR)/debian/ipmitool/usr/share/doc/ipmitool/ChangeLog \
$(CURDIR)/debian/ipmitool/usr/share/doc/ipmitool/changelog
# Compress to avoid lintian warning. Not sure why dh_compress
# isn't fixing this.
gzip -9 $(CURDIR)/debian/ipmitool/usr/share/doc/ipmitool/changelog
# dh_movefiles -a # dh_movefiles -a
# Must not depend on anything. This is to be called by # Must not depend on anything. This is to be called by
# binary-arch/binary-multi # binary-arch/binary-multi
@ -78,27 +89,15 @@ install-arch:
binary-common: binary-common:
dh_testdir dh_testdir
dh_testroot dh_testroot
# dh_installdebconf
dh_installdocs dh_installdocs
# dh_installexamples dh_installchangelogs
# dh_installmenu
# dh_installemacsen
# dh_installpam
# dh_installinit
# dh_installcron
# dh_installmanpages
# dh_installinfo
# dh_undocumented
# dh_installchangelogs
dh_link dh_link
dh_strip dh_strip
dh_compress dh_compress
dh_fixperms dh_fixperms
# You may want to make some executables suid here.
# dh_suidregister
dh_makeshlibs dh_makeshlibs
dh_shlibdeps
dh_installdeb dh_installdeb
# dh_perl
dh_gencontrol dh_gencontrol
dh_md5sums dh_md5sums
dh_builddeb dh_builddeb

6
ipmitool/debian/watch Normal file
View File

@ -0,0 +1,6 @@
# Rename this file to "watch" and then you can run the "uscan" command
# to check for upstream updates and more.
# Site Directory Pattern Version Script
version=2
http://heanet.dl.sourceforge.net/sourceforge/ipmitool/ipmitool-(.*).tar.bz2
# debian uupdate

View File

@ -34,7 +34,7 @@
MAINTAINERCLEANFILES = Makefile.in MAINTAINERCLEANFILES = Makefile.in
man_MANS = ipmitool.1 man_MANS = ipmitool.1 ipmievd.8
EXTRA_DIST = $(man_MANS) EXTRA_DIST = $(man_MANS)

208
ipmitool/doc/ipmievd.8 Normal file
View File

@ -0,0 +1,208 @@
.TH "ipmievd" "8" "" "Duncan Laurie" ""
.SH "NAME"
ipmievd \- IPMI event daemon for sending events to syslog
.SH "SYNOPSIS"
ipmievd [\fB\-c\fR|\fB\-h\fR|\fB\-v\fR|\fB\-V\fR]
\fB\-I\fR \fIopen\fP <\fIopen\fR | \fIsel\fR> [<\fIoption\fP>]
ipmievd [\fB\-c\fR|\fB\-h\fR|\fB\-v\fR|\fB\-V\fR]
\fB\-I\fR \fIlan\fP \fB\-H\fR <\fIhostname\fP>
[\fB\-p\fR <\fIport\fP>]
[\fB\-U\fR <\fIusername\fP>]
[\fB\-A\fR <\fIauthtype\fP>]
[\fB\-L\fR <\fIprivlvl\fP>]
[\fB\-a\fR|\fB\-E\fR|\fB\-P\fR|\fB\-f\fR <\fIpassword\fP>]
[\fB\-o\fR <\fIoemtype\fP>]
\fIsel\fP [<\fIoption\fP>]
ipmievd [\fB\-c\fR|\fB\-h\fR|\fB\-v\fR|\fB\-V\fR]
\fB\-I\fR \fIlanplus\fP \fB\-H\fR <\fIhostname\fP>
[\fB\-p\fR <\fIport\fP>]
[\fB\-U\fR <\fIusername\fP>]
[\fB\-L\fR <\fIprivlvl\fP>]
[\fB\-a\fR|\fB\-E\fR|\fB\-P\fR|\fB\-f\fR <\fIpassword\fP>]
[\fB\-o\fR <\fIoemtype\fP>]
[\fB\-C\fR <\fIciphersuite\fP>]
\fIsel\fR [<\fIoption\fP>]
.SH "DESCRIPTION"
\fBipmievd\fP is a daemon which will listen for events from the
BMC that are being sent to the SEL and also log those messages to
syslog. It is able to run in one of two modes: either using the
Event Message Buffer and asynchronous event notification from the
OpenIPMI kernel driver or actively polling the contents of the
SEL for new events. Upon receipt of an event via either mechanism
it will be logged to syslog with the \fILOG_LOCAL4\fP facility.
It is based on the \fBipmitool\fR utility and shares the same IPMI
interface support and session setup options. Please see the
\fBipmitool\fR manpage for more information on supported IPMI
interfaces.
.SH "OPTIONS"
.TP
\fB\-a\fR
Prompt for the remote server password.
.TP
\fB\-A\fR <\fIauthtype\fP>
Specify an authentication type to use during IPMIv1.5 \fIlan\fP
session activation. Supported types are NONE, PASSWORD, MD5, or OEM.
.TP
\fB\-c\fR
Present output in CSV (comma separated variable) format.
This is not available with all commands.
.TP
\fB\-C\fR <\fIciphersuite\fP>
The remote server authentication, integrity, and encryption algorithms
to use for IPMIv2 \fIlanplus\fP connections. See table 22\-19 in the
IPMIv2 specification. The default is 3 which specifies RAKP\-HMAC\-SHA1
authentication, HMAC\-SHA1\-96 integrity, and AES\-CBC\-128 encryption algorightms.
.TP
\fB\-E\fR
The remote server password is specified by the environment
variable \fIIPMI_PASSWORD\fP.
.TP
\fB\-f\fR <\fIpassword_file\fP>
Specifies a file containing the remote server password. If this
option is absent, or if password_file is empty, the password
will default to NULL.
.TP
\fB\-h\fR
Get basic usage help from the command line.
.TP
\fB\-H\fR <\fIaddress\fP>
Remote server address, can be IP address or hostname. This
option is required for \fIlan\fP and \fIlanplus\fP interfaces.
.TP
\fB\-I\fR <\fIinterface\fP>
Selects IPMI interface to use. Supported interfaces that are
compiled in are visible in the usage help output.
.TP
\fB\-L\fR <\fIprivlvl\fP>
Force session privilege level. Can be CALLBACK, USER,
OPERATOR, ADMIN. Default is ADMIN.
.TP
\fB\-m\fR <\fIlocal_address\fP>
Set the local IPMB address. The default is 0x20 and there
should be no need to change it for normal operation.
.TP
\fB\-o\fR <\fIoemtype\fP>
Select OEM type to support. This usually involves minor hacks
in place in the code to work around quirks in various BMCs from
various manufacturers. Use \fI\-o list\fP to see a list of
current supported OEM types.
.TP
\fB\-p\fR <\fIport\fP>
Remote server UDP port to connect to. Default is 623.
.TP
\fB\-P\fR <\fIpassword\fP>
Remote server password is specified on the command line.
If supported it will be obscured in the process list.
\fBNote!\fR Specifying the password as a command line
option is not recommended.
.TP
\fB\-S\fR <\fIsdr_cache_file\fP>
Use local file for remote SDR cache. Using a local SDR cache
can drastically increase performance for commands that require
knowledge of the entire SDR to perform their function.
.TP
\fB\-t\fR <\fItarget_address\fP>
Bridge IPMI requests to the remote target address.
.TP
\fB\-U\fR <\fIusername\fP>
Remote server username, default is NULL user.
.TP
\fB\-v\fR
Increase verbose output level. This option may be specified
multiple times to increase the level of debug output. If given
three times you will get hexdumps of all incoming and
outgoing packets.
.TP
\fB\-V\fR
Display version information.
.LP
If no password method is specified then ipmievd will prompt the
user for a password. If no password is entered at the prompt,
the remote server password will default to NULL.
.SH "COMMANDS"
.TP
\fIhelp\fP
This can be used to get command\-line help. It may also be
placed at the end of commands to get option usage help.
> ipmievd help
.br
Commands:
open Use OpenIPMI for asyncronous notification of events
sel Poll SEL for notification of events
.TP
\fIopen\fP
This command starts ipmievd with the OpenIPMI event watching
mechanism which relies on the Event Message Buffer feature of
IPMI. This requires a properly installed and configured
OpenIPMI driver on Linux and is only valid to be run through
the \fIopen\fP interface. See the \fBipmitool\fR manpage
and associated documentation for more information on setting
up the OpenIPMI driver.
\fBNote\fR: Some BMC do not support the Event Message Buffer
required for this command. Other BMCs claim to support it but
do not actually deliver events to it. If this is the case please
use the \fIsel\fP method.
.RS
.TP
\fIdaemon\fP
Launch process as a daemon and reparent to init process.
All messages will be sent to syslog. This is the default action.
.TP
\fInodaemon\fP
Do NOT become a daemon, instead log all messages to stderr.
.RE
.TP
\fIsel\fP
This command starts ipmievd with the SEL Polling event watching
mechanism. This will poll the SEL periodically to determine if
new events have been logged. This command should work with all
BMCs and is capable of using the LAN interface as well to monitor
a remote system and log its events to a local syslog.
.RS
.TP
\fIdaemon\fP
Launch process as a daemon and reparent to init process.
All messages will be sent to syslog. This is the default action.
.TP
\fInodaemon\fP
Do NOT become a daemon, instead log all messages to stderr.
.TP
\fItimeout\fP=<\fBseconds\fR>
Time between checks for SEL polling method. Default is 10 seconds.
.RE
.SH "EXAMPLES"
.TP
\fIExample 1\fP: Daemon process watching OpenIPMI for events
> ipmievd \-I open open daemon
.TP
\fIExample 2\fP: Local non\-daemon process checking remote SEL every 30 seconds
> ipmievd \-I lan \-H 1.2.3.4 \-f passfile sel nodaemon timeout=30
.br
Reading Sensors...
.br
Waiting for Events...
.br
.SH "AUTHOR"
Duncan Laurie <duncan@iceblink.org>
.SH "SEE ALSO"
.TP
IPMItool Homepage
http://ipmitool.sourceforge.net
.TP
Intelligent Platform Management Interface Specification
http://www.intel.com/design/servers/ipmi
.TP
OpenIPMI Homepage
http://openipmi.sourceforge.net

File diff suppressed because it is too large Load Diff

View File

@ -39,5 +39,6 @@ noinst_HEADERS = log.h bswap.h helper.h ipmi.h ipmi_intf.h \
ipmi_sdr.h ipmi_sel.h ipmi_sol.h ipmi_mc.h ipmi_raw.h \ ipmi_sdr.h ipmi_sel.h ipmi_sol.h ipmi_mc.h ipmi_raw.h \
ipmi_channel.h ipmi_sensor.h ipmi_event.h ipmi_session.h \ ipmi_channel.h ipmi_sensor.h ipmi_event.h ipmi_session.h \
ipmi_strings.h ipmi_constants.h ipmi_user.h ipmi_pef.h \ ipmi_strings.h ipmi_constants.h ipmi_user.h ipmi_pef.h \
ipmi_oem.h ipmi_oem.h ipmi_isol.h ipmi_sunoem.h ipmi_picmg.h \
ipmi_fwum.h ipmi_main.h ipmi_tsol.h

View File

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

View File

@ -40,6 +40,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <inttypes.h> #include <inttypes.h>
#include <stdio.h> #include <stdio.h>
#include <string.h>
struct valstr { struct valstr {
uint16_t val; uint16_t val;
@ -47,6 +48,9 @@ struct valstr {
}; };
const char * val2str(uint16_t val, const struct valstr * vs); const char * val2str(uint16_t val, const struct valstr * vs);
uint16_t str2val(const char * str, const struct valstr * vs); uint16_t str2val(const char * str, const struct valstr * vs);
void print_valstr(const struct valstr * vs, const char * title, int loglevel);
void print_valstr_2col(const struct valstr * vs, const char * title, int loglevel);
uint16_t buf2short(uint8_t * buf); uint16_t buf2short(uint8_t * buf);
uint32_t buf2long(uint8_t * buf); uint32_t buf2long(uint8_t * buf);
@ -54,6 +58,7 @@ const char * buf2str(uint8_t * buf, int len);
void printbuf(const uint8_t * buf, int len, const char * desc); void printbuf(const uint8_t * buf, int len, const char * desc);
uint8_t ipmi_csum(uint8_t * d, int s); uint8_t ipmi_csum(uint8_t * d, int s);
FILE * ipmi_open_file(const char * file, int rw); FILE * ipmi_open_file(const char * file, int rw);
void ipmi_start_daemon(void);
#define ipmi_open_file_read(file) ipmi_open_file(file, 0) #define ipmi_open_file_read(file) ipmi_open_file(file, 0)
#define ipmi_open_file_write(file) ipmi_open_file(file, 1) #define ipmi_open_file_write(file) ipmi_open_file(file, 1)
@ -62,4 +67,16 @@ FILE * ipmi_open_file(const char * file, int rw);
# define __min(a, b) ((a) < (b) ? (a) : (b)) # define __min(a, b) ((a) < (b) ? (a) : (b))
#endif #endif
#ifndef __max
# define __max(a, b) ((a) > (b) ? (a) : (b))
#endif
#ifndef __minlen
# define __minlen(a, b) ({ int x=strlen(a); int y=strlen(b); (x < y) ? x : y;})
#endif
#ifndef __maxlen
# define __maxlen(a, b) ({ int x=strlen(a); int y=strlen(b); (x > y) ? x : y;})
#endif
#endif /* IPMI_HELPER_H */ #endif /* IPMI_HELPER_H */

View File

@ -49,6 +49,7 @@
/* From table 13.16 of the IPMI v2 specification */ /* From table 13.16 of the IPMI v2 specification */
#define IPMI_PAYLOAD_TYPE_IPMI 0x00 #define IPMI_PAYLOAD_TYPE_IPMI 0x00
#define IPMI_PAYLOAD_TYPE_SOL 0x01 #define IPMI_PAYLOAD_TYPE_SOL 0x01
#define IPMI_PAYLOAD_TYPE_OEM 0x02
#define IPMI_PAYLOAD_TYPE_RMCP_OPEN_REQUEST 0x10 #define IPMI_PAYLOAD_TYPE_RMCP_OPEN_REQUEST 0x10
#define IPMI_PAYLOAD_TYPE_RMCP_OPEN_RESPONSE 0x11 #define IPMI_PAYLOAD_TYPE_RMCP_OPEN_RESPONSE 0x11
#define IPMI_PAYLOAD_TYPE_RAKP_1 0x12 #define IPMI_PAYLOAD_TYPE_RAKP_1 0x12
@ -56,13 +57,13 @@
#define IPMI_PAYLOAD_TYPE_RAKP_3 0x14 #define IPMI_PAYLOAD_TYPE_RAKP_3 0x14
#define IPMI_PAYLOAD_TYPE_RAKP_4 0x15 #define IPMI_PAYLOAD_TYPE_RAKP_4 0x15
extern int verbose; extern int verbose;
extern int csv_output; extern int csv_output;
struct ipmi_rq { struct ipmi_rq {
struct { struct {
uint8_t netfn; uint8_t netfn:6;
uint8_t lun:2;
uint8_t cmd; uint8_t cmd;
uint8_t target_cmd; uint8_t target_cmd;
uint16_t data_len; uint16_t data_len;
@ -70,7 +71,6 @@ struct ipmi_rq {
} msg; } msg;
}; };
/* /*
* This is what the sendrcv_v2() function would take as an argument. The common case * This is what the sendrcv_v2() function would take as an argument. The common case
* is for payload_type to be IPMI_PAYLOAD_TYPE_IPMI. * is for payload_type to be IPMI_PAYLOAD_TYPE_IPMI.
@ -134,8 +134,6 @@ struct ipmi_v2_payload {
} payload; } payload;
}; };
struct ipmi_rq_entry { struct ipmi_rq_entry {
struct ipmi_rq req; struct ipmi_rq req;
struct ipmi_intf *intf; struct ipmi_intf *intf;
@ -145,9 +143,6 @@ struct ipmi_rq_entry {
struct ipmi_rq_entry *next; struct ipmi_rq_entry *next;
}; };
struct ipmi_rs { struct ipmi_rs {
uint8_t ccode; uint8_t ccode;
uint8_t data[IPMI_BUF_SIZE]; uint8_t data[IPMI_BUF_SIZE];
@ -178,7 +173,6 @@ struct ipmi_rs {
uint16_t msglen; uint16_t msglen;
} session; } session;
/* /*
* A union of the different possible payload meta-data * A union of the different possible payload meta-data
*/ */
@ -230,8 +224,6 @@ struct ipmi_rs {
} payload; } payload;
}; };
#define IPMI_NETFN_CHASSIS 0x0 #define IPMI_NETFN_CHASSIS 0x0
#define IPMI_NETFN_BRIDGE 0x2 #define IPMI_NETFN_BRIDGE 0x2
#define IPMI_NETFN_SE 0x4 #define IPMI_NETFN_SE 0x4
@ -239,7 +231,9 @@ struct ipmi_rs {
#define IPMI_NETFN_FIRMWARE 0x8 #define IPMI_NETFN_FIRMWARE 0x8
#define IPMI_NETFN_STORAGE 0xa #define IPMI_NETFN_STORAGE 0xa
#define IPMI_NETFN_TRANSPORT 0xc #define IPMI_NETFN_TRANSPORT 0xc
#define IPMI_NETFN_PICMG 0x2C
#define IPMI_NETFN_ISOL 0x34 #define IPMI_NETFN_ISOL 0x34
#define IPMI_NETFN_TSOL 0x30
#define IPMI_BMC_SLAVE_ADDR 0x20 #define IPMI_BMC_SLAVE_ADDR 0x20
#define IPMI_REMOTE_SWID 0x81 #define IPMI_REMOTE_SWID 0x81

View File

@ -42,6 +42,7 @@
#endif #endif
#include <ipmitool/ipmi.h> #include <ipmitool/ipmi.h>
#define IPMI_GET_CHANNEL_AUTH_CAP 0x38 #define IPMI_GET_CHANNEL_AUTH_CAP 0x38
#define IPMI_GET_CHANNEL_ACCESS 0x41 #define IPMI_GET_CHANNEL_ACCESS 0x41
#define IPMI_GET_CHANNEL_INFO 0x42 #define IPMI_GET_CHANNEL_INFO 0x42
@ -50,6 +51,7 @@
#define IPMI_SET_USER_NAME 0x45 #define IPMI_SET_USER_NAME 0x45
#define IPMI_GET_USER_NAME 0x46 #define IPMI_GET_USER_NAME 0x46
#define IPMI_SET_USER_PASSWORD 0x47 #define IPMI_SET_USER_PASSWORD 0x47
#define IPMI_GET_CHANNEL_CIPHER_SUITES 0x54
/* /*

View File

@ -51,6 +51,9 @@
#define IPMI_CHASSIS_POLICY_PREVIOUS 0x1 #define IPMI_CHASSIS_POLICY_PREVIOUS 0x1
#define IPMI_CHASSIS_POLICY_ALWAYS_OFF 0x0 #define IPMI_CHASSIS_POLICY_ALWAYS_OFF 0x0
int ipmi_chassis_main(struct ipmi_intf *, int, char **); int ipmi_chassis_power_status(struct ipmi_intf * intf);
int ipmi_chassis_power_control(struct ipmi_intf * intf, uint8_t ctl);
int ipmi_chassis_main(struct ipmi_intf * intf, int argc, char ** argv);
int ipmi_power_main(struct ipmi_intf * intf, int argc, char ** argv);
#endif /*IPMI_CHASSIS_H*/ #endif /*IPMI_CHASSIS_H*/

View File

@ -70,6 +70,7 @@
#define IPMI_SESSION_AUTHTYPE_OEM 0x5 #define IPMI_SESSION_AUTHTYPE_OEM 0x5
#define IPMI_SESSION_AUTHTYPE_RMCP_PLUS 0x6 #define IPMI_SESSION_AUTHTYPE_RMCP_PLUS 0x6
#define IPMI_SESSION_PRIV_UNSPECIFIED 0x0
#define IPMI_SESSION_PRIV_CALLBACK 0x1 #define IPMI_SESSION_PRIV_CALLBACK 0x1
#define IPMI_SESSION_PRIV_USER 0x2 #define IPMI_SESSION_PRIV_USER 0x2
#define IPMI_SESSION_PRIV_OPERATOR 0x3 #define IPMI_SESSION_PRIV_OPERATOR 0x3
@ -81,7 +82,7 @@
#define IPMI_SET_IN_PROGRESS_COMMIT_WRITE 0x02 #define IPMI_SET_IN_PROGRESS_COMMIT_WRITE 0x02
#define IPMI_CHANNEL_MEDIUM_RESERVED 0x0 #define IPMI_CHANNEL_MEDIUM_RESERVED 0x0
#define IPMI_CHANNEL_MEDIUM_IPMB 0x1 #define IPMI_CHANNEL_MEDIUM_IPMB_I2C 0x1
#define IPMI_CHANNEL_MEDIUM_ICMB_1 0x2 #define IPMI_CHANNEL_MEDIUM_ICMB_1 0x2
#define IPMI_CHANNEL_MEDIUM_ICMB_09 0x3 #define IPMI_CHANNEL_MEDIUM_ICMB_09 0x3
#define IPMI_CHANNEL_MEDIUM_LAN 0x4 #define IPMI_CHANNEL_MEDIUM_LAN 0x4
@ -94,4 +95,33 @@
#define IPMI_CHANNEL_MEDIUM_USB_2 0xb #define IPMI_CHANNEL_MEDIUM_USB_2 0xb
#define IPMI_CHANNEL_MEDIUM_SYSTEM 0xc #define IPMI_CHANNEL_MEDIUM_SYSTEM 0xc
#define IPMI_CHASSIS_CTL_POWER_DOWN 0x0
#define IPMI_CHASSIS_CTL_POWER_UP 0x1
#define IPMI_CHASSIS_CTL_POWER_CYCLE 0x2
#define IPMI_CHASSIS_CTL_HARD_RESET 0x3
#define IPMI_CHASSIS_CTL_PULSE_DIAG 0x4
#define IPMI_CHASSIS_CTL_ACPI_SOFT 0x5
#define IPMI_CHASSIS_POLICY_NO_CHANGE 0x3
#define IPMI_CHASSIS_POLICY_ALWAYS_ON 0x2
#define IPMI_CHASSIS_POLICY_PREVIOUS 0x1
#define IPMI_CHASSIS_POLICY_ALWAYS_OFF 0x0
/* From table 13-17 of the IPMI v2 specification */
#define IPMI_AUTH_RAKP_NONE 0x00
#define IPMI_AUTH_RAKP_HMAC_SHA1 0x01
#define IPMI_AUTH_RAKP_HMAC_MD5 0x02
/* From table 13-18 of the IPMI v2 specification */
#define IPMI_INTEGRITY_NONE 0x00
#define IPMI_INTEGRITY_HMAC_SHA1_96 0x01
#define IPMI_INTEGRITY_HMAC_MD5_128 0x02
#define IPMI_INTEGRITY_MD5_128 0x03
/* From table 13-19 of the IPMI v2 specfication */
#define IPMI_CRYPT_NONE 0x00
#define IPMI_CRYPT_AES_CBC_128 0x01
#define IPMI_CRYPT_XRC4_128 0x02
#define IPMI_CRYPT_XRC4_40 0x03
#endif /*IPMI_CONSTANTS_H*/ #endif /*IPMI_CONSTANTS_H*/

View File

@ -42,6 +42,23 @@
#endif #endif
#include <ipmitool/ipmi.h> #include <ipmitool/ipmi.h>
#define EVENT_DIR_ASSERT 0
#define EVENT_DIR_DEASSERT 1
struct platform_event_msg {
uint8_t evm_rev;
uint8_t sensor_type;
uint8_t sensor_num;
#if WORDS_BIGENDIAN
uint8_t event_dir : 1;
uint8_t event_type : 7;
#else
uint8_t event_type : 7;
uint8_t event_dir : 1;
#endif
uint8_t event_data[3];
} __attribute__((packed));
int ipmi_event_main(struct ipmi_intf *, int, char **); int ipmi_event_main(struct ipmi_intf *, int, char **);
#endif /*IPMI_EVENT_H*/ #endif /*IPMI_EVENT_H*/

View File

@ -122,6 +122,7 @@ struct fru_multirec_header {
#define FRU_RECORD_TYPE_MANAGEMENT_ACCESS 0x03 #define FRU_RECORD_TYPE_MANAGEMENT_ACCESS 0x03
#define FRU_RECORD_TYPE_BASE_COMPATIBILITY 0x04 #define FRU_RECORD_TYPE_BASE_COMPATIBILITY 0x04
#define FRU_RECORD_TYPE_EXTENDED_COMPATIBILITY 0x05 #define FRU_RECORD_TYPE_EXTENDED_COMPATIBILITY 0x05
#define FRU_RECORD_TYPE_PICMG_EXTENSION 0xc0
uint8_t type; uint8_t type;
uint8_t format; uint8_t format;
uint8_t len; uint8_t len;
@ -174,8 +175,7 @@ struct fru_multirec_powersupply {
} __attribute__ ((packed)); } __attribute__ ((packed));
static const char *combined_voltage_desc[] __attribute__ ((unused)) = { static const char *combined_voltage_desc[] __attribute__ ((unused)) = {
"12 V", "-12 V", "5 V", "3.3 V" "12 V", "-12 V", "5 V", "3.3 V"};
};
struct fru_multirec_dcoutput { struct fru_multirec_dcoutput {
#if WORDS_BIGENDIAN #if WORDS_BIGENDIAN
@ -211,16 +211,110 @@ struct fru_multirec_dcload {
uint16_t max_current; uint16_t max_current;
} __attribute__ ((packed)); } __attribute__ ((packed));
struct fru_multirec_picmgext_header {
unsigned char mfg_id[3];
#define FRU_PICMG_BACKPLANE_P2P 0x04
#define FRU_PICMG_ADDRESS_TABLE 0x10
#define FRU_PICMG_SHELF_POWER_DIST 0x11
#define FRU_PICMG_SHELF_ACTIVATION 0x12
#define FRU_PICMG_SHMC_IP_CONN 0x13
#define FRU_PICMG_BOARD_P2P 0x14
#define FRU_AMC_CURRENT 0x16
#define FRU_AMC_ACTIVATION 0x17
#define FRU_AMC_CARRIER_P2P 0x18
#define FRU_AMC_P2P 0x19
#define FRU_AMC_CARRIER_INFO 0x1a
unsigned char record_id;
unsigned char record_version;
} __attribute__ ((packed));
struct fru_picmgext_guid {
unsigned char guid[16];
} __attribute__ ((packed));
struct fru_picmgext_link_desc {
#ifndef WORDS_BIGENDIAN
unsigned int designator:12;
#define FRU_PICMGEXT_LINK_TYPE_BASE 0x01
#define FRU_PICMGEXT_LINK_TYPE_FABRIC_ETHERNET 0x02
#define FRU_PICMGEXT_LINK_TYPE_FABRIC_INFINIBAND 0x03
#define FRU_PICMGEXT_LINK_TYPE_FABRIC_STAR 0x04
#define FRU_PICMGEXT_LINK_TYPE_PCIE 0x05
unsigned int type:8;
unsigned int ext:4;
unsigned int grouping:8;
#else
unsigned int grouping:8;
unsigned int ext:4;
#define FRU_PICMGEXT_LINK_TYPE_BASE 0x01
#define FRU_PICMGEXT_LINK_TYPE_FABRIC_ETHERNET 0x02
#define FRU_PICMGEXT_LINK_TYPE_FABRIC_INFINIBAND 0x03
#define FRU_PICMGEXT_LINK_TYPE_FABRIC_STAR 0x04
#define FRU_PICMGEXT_LINK_TYPE_PCIE 0x05
unsigned int type:8;
unsigned int designator:12;
#endif
} __attribute__ ((packed));
struct fru_picmgext_chn_desc {
#ifndef WORDS_BIGENDIAN
unsigned char remote_slot:8;
unsigned char remote_chn:5;
unsigned char local_chn:5;
unsigned char:6;
#else
unsigned char:6;
unsigned char local_chn:5;
unsigned char remote_chn:5;
unsigned char remote_slot:8;
#endif
} __attribute__ ((packed));
struct fru_picmgext_slot_desc {
unsigned char chan_type;
unsigned char slot_addr;
unsigned char chn_count;
} __attribute__ ((packed));
#define FRU_PICMGEXT_DESIGN_IF_BASE 0x00
#define FRU_PICMGEXT_DESIGN_IF_FABRIC 0x01
#define FRU_PICMGEXT_DESIGN_IF_UPDATE_CHANNEL 0x02
#define FRU_PICMGEXT_DESIGN_IF_RESERVED 0x03
struct fru_picmgext_activation_record {
unsigned char ibmb_addr;
unsigned char max_module_curr;
unsigned char reserved;
} __attribute__ ((packed));
struct fru_picmgext_carrier_p2p_record {
unsigned char resource_id;
unsigned char p2p_count;
} __attribute__ ((packed));
struct fru_picmgext_carrier_p2p_descriptor {
#ifndef WORDS_BIGENDIAN
unsigned char remote_resource_id;
unsigned short remote_port:5;
unsigned short local_port:5;
unsigned short reserved:6;
#else
unsigned short reserved:6;
unsigned short local_port:5;
unsigned short remote_port:5;
unsigned char remote_resource_id;
#endif
} __attribute__ ((packed));
static const char *chassis_type_desc[] __attribute__ ((unused)) = { static const char *chassis_type_desc[] __attribute__ ((unused)) = {
"Unspecified", "Other", "Unknown", "Unspecified", "Other", "Unknown",
"Desktop", "Low Profile Desktop", "Pizza Box", "Desktop", "Low Profile Desktop", "Pizza Box",
"Mini Tower", "Tower", "Mini Tower", "Tower",
"Portable", "LapTop", "Notebook", "Hand Held", "Docking Station", "Portable", "LapTop", "Notebook", "Hand Held",
"All in One", "Sub Notebook", "Space-saving", "Lunch Box", "Docking Station", "All in One", "Sub Notebook",
"Main Server Chassis", "Expansion Chassis", "SubChassis", "Space-saving", "Lunch Box", "Main Server Chassis",
"Bus Expansion Chassis", "Peripheral Chassis", "RAID Chassis", "Expansion Chassis", "SubChassis", "Bus Expansion Chassis",
"Rack Mount Chassis" "Peripheral Chassis", "RAID Chassis", "Rack Mount Chassis"};
};
int ipmi_fru_main(struct ipmi_intf *intf, int argc, char **argv); int ipmi_fru_main(struct ipmi_intf *intf, int argc, char **argv);
int ipmi_fru_print(struct ipmi_intf *intf, struct sdr_record_fru_locator *fru); int ipmi_fru_print(struct ipmi_intf *intf, struct sdr_record_fru_locator *fru);

View File

@ -0,0 +1,46 @@
/*
* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistribution of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistribution in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind.
* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
* SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE
* FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
* SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
* OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
* PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
* LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed or intended for use
* in the design, construction, operation or maintenance of any nuclear
* facility.
*/
#ifndef IPMI_KFWUM_H
#define IPMI_KFWUM_H
#include <inttypes.h>
#include <ipmitool/ipmi.h>
int ipmi_fwum_main(struct ipmi_intf *, int, char **);
#endif /* IPMI_KFWUM_H */

View File

@ -68,7 +68,7 @@ enum LANPLUS_SESSION_STATE {
struct ipmi_session { struct ipmi_session {
uint8_t hostname[64]; uint8_t hostname[64];
uint8_t username[16]; uint8_t username[17];
uint8_t authcode[IPMI_AUTHCODE_BUFFER_SIZE + 1]; uint8_t authcode[IPMI_AUTHCODE_BUFFER_SIZE + 1];
uint8_t challenge[16]; uint8_t challenge[16];
uint8_t authtype; uint8_t authtype;
@ -81,9 +81,12 @@ struct ipmi_session {
uint8_t authstatus; uint8_t authstatus;
uint8_t authextra; uint8_t authextra;
uint8_t privlvl; uint8_t privlvl;
uint8_t cipher_suite_id;
char sol_escape_char;
int password; int password;
int port; int port;
int active; int active;
int retry;
uint32_t session_id; uint32_t session_id;
uint32_t in_seq; uint32_t in_seq;
@ -100,6 +103,9 @@ struct ipmi_session {
enum LANPLUS_SESSION_STATE session_state; enum LANPLUS_SESSION_STATE session_state;
/* These are the algorithms agreed upon for the session */ /* These are the algorithms agreed upon for the session */
uint8_t requested_auth_alg;
uint8_t requested_integrity_alg;
uint8_t requested_crypt_alg;
uint8_t auth_alg; uint8_t auth_alg;
uint8_t integrity_alg; uint8_t integrity_alg;
uint8_t crypt_alg; uint8_t crypt_alg;
@ -144,17 +150,32 @@ struct ipmi_session {
} sol_data; } sol_data;
}; };
struct ipmi_cmd {
int (*func)(struct ipmi_intf * intf, int argc, char ** argv);
const char * name;
const char * desc;
};
struct ipmi_intf_support {
const char * name;
int supported;
};
struct ipmi_intf { struct ipmi_intf {
char name[16]; char name[16];
char desc[128]; char desc[128];
int fd; int fd;
int opened; int opened;
int abort; int abort;
int noanswer;
struct ipmi_session * session; struct ipmi_session * session;
struct ipmi_oem_handle * oem; struct ipmi_oem_handle * oem;
struct ipmi_cmd * cmdlist;
uint32_t my_addr; uint32_t my_addr;
uint32_t target_addr; uint32_t target_addr;
uint8_t target_lun;
uint8_t target_channel;
int (*setup)(struct ipmi_intf * intf); int (*setup)(struct ipmi_intf * intf);
int (*open)(struct ipmi_intf * intf); int (*open)(struct ipmi_intf * intf);
@ -167,14 +188,19 @@ struct ipmi_intf {
}; };
struct ipmi_intf * ipmi_intf_load(char * name); struct ipmi_intf * ipmi_intf_load(char * name);
void ipmi_intf_print(void); void ipmi_intf_print(struct ipmi_intf_support * intflist);
void ipmi_intf_session_set_hostname(struct ipmi_intf * intf, char * hostname); void ipmi_intf_session_set_hostname(struct ipmi_intf * intf, char * hostname);
void ipmi_intf_session_set_username(struct ipmi_intf * intf, char * username); void ipmi_intf_session_set_username(struct ipmi_intf * intf, char * username);
void ipmi_intf_session_set_password(struct ipmi_intf * intf, char * password); void ipmi_intf_session_set_password(struct ipmi_intf * intf, char * password);
void ipmi_intf_session_set_privlvl(struct ipmi_intf * intf, uint8_t privlvl); void ipmi_intf_session_set_privlvl(struct ipmi_intf * intf, uint8_t privlvl);
void ipmi_intf_session_set_cipher_suite_id(struct ipmi_intf * intf, uint8_t cipher_suite_id);
void ipmi_intf_session_set_sol_escape_char(struct ipmi_intf * intf, char sol_escape_char);
void ipmi_intf_session_set_kgkey(struct ipmi_intf * intf, char * kgkey);
void ipmi_intf_session_set_port(struct ipmi_intf * intf, int port); void ipmi_intf_session_set_port(struct ipmi_intf * intf, int port);
void ipmi_intf_session_set_authtype(struct ipmi_intf * intf, uint8_t authtype); void ipmi_intf_session_set_authtype(struct ipmi_intf * intf, uint8_t authtype);
void ipmi_intf_session_set_timeout(struct ipmi_intf * intf, uint32_t timeout);
void ipmi_intf_session_set_retry(struct ipmi_intf * intf, int retry);
void ipmi_cleanup(struct ipmi_intf * intf); void ipmi_cleanup(struct ipmi_intf * intf);
#endif /* IPMI_INTF_H */ #endif /* IPMI_INTF_H */

View File

@ -0,0 +1,60 @@
/*
* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistribution of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistribution in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind.
* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
* SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE
* FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
* SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
* OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
* PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
* LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed or intended for use
* in the design, construction, operation or maintenance of any nuclear
* facility.
*/
#ifndef IPMI_ISOL_H
#define IPMI_ISOL_H
#include <ipmitool/ipmi.h>
#define ACTIVATE_ISOL 0x01
#define SET_ISOL_CONFIG 0x03
#define GET_ISOL_CONFIG 0x04
#define ISOL_ENABLE_PARAM 0x01
#define ISOL_AUTHENTICATION_PARAM 0x02
#define ISOL_ENABLE_FLAG 0x01
#define ISOL_PRIVILEGE_LEVEL_USER 0x02
#define ISOL_BAUD_RATE_PARAM 0x05
#define ISOL_BAUD_RATE_9600 0x06
#define ISOL_BAUD_RATE_19200 0x07
#define ISOL_BAUD_RATE_38400 0x08
#define ISOL_BAUD_RATE_57600 0x09
#define ISOL_BAUD_RATE_115200 0x0A
#define ISOL_PREFERRED_BAUD_RATE 0x07
int ipmi_isol_main(struct ipmi_intf *, int, char **);
#endif /* IPMI_SOL_H */

View File

@ -46,7 +46,7 @@
# define IPMI_LAN_SUSPEND_ARP_GRAT (1) # define IPMI_LAN_SUSPEND_ARP_GRAT (1)
#define IPMI_LAN_GET_STAT 0x04 #define IPMI_LAN_GET_STAT 0x04
#define IPMI_CHANNEL_NUMBER_MAX 0xd #define IPMI_CHANNEL_NUMBER_MAX 0xe
#define IPMI_LANP_TIMEOUT 3 #define IPMI_LANP_TIMEOUT 3
#define IPMI_LANP_RETRIES 10 #define IPMI_LANP_RETRIES 10
@ -60,21 +60,26 @@ enum {
IPMI_LANP_AUTH_TYPE_ENABLE, IPMI_LANP_AUTH_TYPE_ENABLE,
IPMI_LANP_IP_ADDR, IPMI_LANP_IP_ADDR,
IPMI_LANP_IP_ADDR_SRC, IPMI_LANP_IP_ADDR_SRC,
IPMI_LANP_MAC_ADDR, IPMI_LANP_MAC_ADDR, /* 5 */
IPMI_LANP_SUBNET_MASK, IPMI_LANP_SUBNET_MASK,
IPMI_LANP_IP_HEADER, IPMI_LANP_IP_HEADER,
IPMI_LANP_PRI_RMCP_PORT, IPMI_LANP_PRI_RMCP_PORT,
IPMI_LANP_SEC_RMCP_PORT, IPMI_LANP_SEC_RMCP_PORT,
IPMI_LANP_BMC_ARP, IPMI_LANP_BMC_ARP, /* 10 */
IPMI_LANP_GRAT_ARP, IPMI_LANP_GRAT_ARP,
IPMI_LANP_DEF_GATEWAY_IP, IPMI_LANP_DEF_GATEWAY_IP,
IPMI_LANP_DEF_GATEWAY_MAC, IPMI_LANP_DEF_GATEWAY_MAC,
IPMI_LANP_BAK_GATEWAY_IP, IPMI_LANP_BAK_GATEWAY_IP,
IPMI_LANP_BAK_GATEWAY_MAC, IPMI_LANP_BAK_GATEWAY_MAC, /* 15 */
IPMI_LANP_SNMP_STRING, IPMI_LANP_SNMP_STRING,
IPMI_LANP_NUM_DEST, IPMI_LANP_NUM_DEST,
IPMI_LANP_DEST_TYPE, IPMI_LANP_DEST_TYPE,
IPMI_LANP_DEST_ADDR, IPMI_LANP_DEST_ADDR,
IPMI_LANP_VLAN_ID, /* 20 */
IPMI_LANP_VLAN_PRIORITY,
IPMI_LANP_RMCP_CIPHER_SUPPORT,
IPMI_LANP_RMCP_CIPHERS,
IPMI_LANP_RMCP_PRIV_LEVELS,
IPMI_LANP_OEM_ALERT_STRING=96, IPMI_LANP_OEM_ALERT_STRING=96,
IPMI_LANP_ALERT_RETRY=97, IPMI_LANP_ALERT_RETRY=97,
IPMI_LANP_UTC_OFFSET=98, IPMI_LANP_UTC_OFFSET=98,
@ -96,27 +101,32 @@ static struct lan_param {
{ IPMI_LANP_AUTH_TYPE_ENABLE, 5, "Auth Type Enable" }, { IPMI_LANP_AUTH_TYPE_ENABLE, 5, "Auth Type Enable" },
{ IPMI_LANP_IP_ADDR, 4, "IP Address" }, { IPMI_LANP_IP_ADDR, 4, "IP Address" },
{ IPMI_LANP_IP_ADDR_SRC, 1, "IP Address Source" }, { IPMI_LANP_IP_ADDR_SRC, 1, "IP Address Source" },
{ IPMI_LANP_MAC_ADDR, 6, "MAC Address" }, { IPMI_LANP_MAC_ADDR, 6, "MAC Address" }, /* 5 */
{ IPMI_LANP_SUBNET_MASK, 4, "Subnet Mask" }, { IPMI_LANP_SUBNET_MASK, 4, "Subnet Mask" },
{ IPMI_LANP_IP_HEADER, 3, "IP Header" }, { IPMI_LANP_IP_HEADER, 3, "IP Header" },
{ IPMI_LANP_PRI_RMCP_PORT, 2, "Primary RMCP Port" }, { IPMI_LANP_PRI_RMCP_PORT, 2, "Primary RMCP Port" },
{ IPMI_LANP_SEC_RMCP_PORT, 2, "Secondary RMCP Port" }, { IPMI_LANP_SEC_RMCP_PORT, 2, "Secondary RMCP Port" },
{ IPMI_LANP_BMC_ARP, 1, "BMC ARP Control" }, { IPMI_LANP_BMC_ARP, 1, "BMC ARP Control" }, /* 10 */
{ IPMI_LANP_GRAT_ARP, 1, "Gratituous ARP Intrvl" }, { IPMI_LANP_GRAT_ARP, 1, "Gratituous ARP Intrvl" },
{ IPMI_LANP_DEF_GATEWAY_IP, 4, "Default Gateway IP" }, { IPMI_LANP_DEF_GATEWAY_IP, 4, "Default Gateway IP" },
{ IPMI_LANP_DEF_GATEWAY_MAC, 6, "Default Gateway MAC" }, { IPMI_LANP_DEF_GATEWAY_MAC, 6, "Default Gateway MAC" },
{ IPMI_LANP_BAK_GATEWAY_IP, 4, "Backup Gateway IP" }, { IPMI_LANP_BAK_GATEWAY_IP, 4, "Backup Gateway IP" },
{ IPMI_LANP_BAK_GATEWAY_MAC, 6, "Backup Gateway MAC" }, { IPMI_LANP_BAK_GATEWAY_MAC, 6, "Backup Gateway MAC" }, /* 15 */
{ IPMI_LANP_SNMP_STRING, 18, "SNMP Community String" }, { IPMI_LANP_SNMP_STRING, 18, "SNMP Community String" },
{ IPMI_LANP_NUM_DEST, 1, "Number of Destinations"}, { IPMI_LANP_NUM_DEST, 1, "Number of Destinations"},
{ IPMI_LANP_DEST_TYPE, 4, "Destination Type" }, { IPMI_LANP_DEST_TYPE, 4, "Destination Type" },
{ IPMI_LANP_DEST_ADDR, 13, "Destination Addresses" }, { IPMI_LANP_DEST_ADDR, 13, "Destination Addresses" },
{ IPMI_LANP_OEM_ALERT_STRING, 28, "OEM Alert String" }, { IPMI_LANP_VLAN_ID, 2, "802.1q VLAN ID" }, /* 20 */
{ IPMI_LANP_VLAN_PRIORITY, 1, "802.1q VLAN Priority" },
{ IPMI_LANP_RMCP_CIPHER_SUPPORT,1, "RMCP+ Cipher Suite Count" },
{ IPMI_LANP_RMCP_CIPHERS, 16, "RMCP+ Cipher Suites" },
{ IPMI_LANP_RMCP_PRIV_LEVELS, 9, "Cipher Suite Priv Max" },
{ IPMI_LANP_OEM_ALERT_STRING, 28, "OEM Alert String" }, /* 25 */
{ IPMI_LANP_ALERT_RETRY, 1, "Alert Retry Algorithm" }, { IPMI_LANP_ALERT_RETRY, 1, "Alert Retry Algorithm" },
{ IPMI_LANP_UTC_OFFSET, 3, "UTC Offset" }, { IPMI_LANP_UTC_OFFSET, 3, "UTC Offset" },
{ IPMI_LANP_DHCP_SERVER_IP, 4, "DHCP Server IP" }, { IPMI_LANP_DHCP_SERVER_IP, 4, "DHCP Server IP" },
{ IPMI_LANP_DHCP_SERVER_MAC, 6, "DHDP Server MAC" }, { IPMI_LANP_DHCP_SERVER_MAC, 6, "DHDP Server MAC" },
{ IPMI_LANP_DHCP_ENABLE, 1, "DHCP Enable" }, { IPMI_LANP_DHCP_ENABLE, 1, "DHCP Enable" }, /* 30 */
{ IPMI_LANP_CHAN_ACCESS_MODE, 2, "Channel Access Mode" }, { IPMI_LANP_CHAN_ACCESS_MODE, 2, "Channel Access Mode" },
{ -1 } { -1 }
}; };

View File

@ -0,0 +1,46 @@
/*
* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistribution of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistribution in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind.
* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
* SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE
* FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
* SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
* OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
* PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
* LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed or intended for use
* in the design, construction, operation or maintenance of any nuclear
* facility.
*/
#ifndef IPMI_MAIN_H
#define IPMI_MAIN_H
#include <ipmitool/ipmi_intf.h>
int ipmi_main(int argc, char ** argv, struct ipmi_cmd * cmdlist, struct ipmi_intf_support * intflist);
void ipmi_cmd_print(struct ipmi_cmd * cmdlist);
int ipmi_cmd_run(struct ipmi_intf * intf, char * name, int argc, char ** argv);
#endif /* IPMI_MAIN_H */

View File

@ -45,6 +45,7 @@
#define BMC_GET_SELF_TEST 0x04 #define BMC_GET_SELF_TEST 0x04
#define BMC_SET_GLOBAL_ENABLES 0x2e #define BMC_SET_GLOBAL_ENABLES 0x2e
#define BMC_GET_GLOBAL_ENABLES 0x2f #define BMC_GET_GLOBAL_ENABLES 0x2f
#define BMC_GET_GUID 0x37
int ipmi_mc_main(struct ipmi_intf *, int, char **); int ipmi_mc_main(struct ipmi_intf *, int, char **);
@ -83,4 +84,24 @@ struct ipm_devid_rsp {
#define IPM_DEV_ADTL_SUPPORT_BITS (8) #define IPM_DEV_ADTL_SUPPORT_BITS (8)
struct ipm_selftest_rsp {
unsigned char code;
unsigned char test;
} __attribute__ ((packed));
#define IPM_SFT_CODE_OK 0x55
#define IPM_SFT_CODE_NOT_IMPLEMENTED 0x56
#define IPM_SFT_CODE_DEV_CORRUPTED 0x57
#define IPM_SFT_CODE_FATAL_ERROR 0x58
#define IPM_SFT_CODE_RESERVED 0xff
#define IPM_SELFTEST_SEL_ERROR 0x80
#define IPM_SELFTEST_SDR_ERROR 0x40
#define IPM_SELFTEST_FRU_ERROR 0x20
#define IPM_SELFTEST_IPMB_ERROR 0x10
#define IPM_SELFTEST_SDRR_EMPTY 0x08
#define IPM_SELFTEST_INTERNAL_USE 0x04
#define IPM_SELFTEST_FW_BOOTBLOCK 0x02
#define IPM_SELFTEST_FW_CORRUPTED 0x01
#endif /*IPMI_MC_H */ #endif /*IPMI_MC_H */

View File

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

View File

@ -0,0 +1,75 @@
/*
(C) Kontron
*/
#ifndef _IPMI_PICMG_H_
#define _IPMI_PICMG_H_
#include <ipmitool/ipmi.h>
/* PICMG commands */
#define PICMG_GET_PICMG_PROPERTIES_CMD 0x00
#define PICMG_GET_ADDRESS_INFO_CMD 0x01
#define PICMG_GET_SHELF_ADDRESS_INFO_CMD 0x02
#define PICMG_SET_SHELF_ADDRESS_INFO_CMD 0x03
#define PICMG_FRU_CONTROL_CMD 0x04
#define PICMG_GET_FRU_LED_PROPERTIES_CMD 0x05
#define PICMG_GET_LED_COLOR_CAPABILITIES_CMD 0x06
#define PICMG_SET_FRU_LED_STATE_CMD 0x07
#define PICMG_GET_FRU_LED_STATE_CMD 0x08
#define PICMG_SET_IPMB_CMD 0x09
#define PICMG_SET_FRU_POLICY_CMD 0x0A
#define PICMG_GET_FRU_POLICY_CMD 0x0B
#define PICMG_FRU_ACTIVATION_CMD 0x0C
#define PICMG_GET_DEVICE_LOCATOR_RECORD_CMD 0x0D
#define PICMG_SET_PORT_STATE_CMD 0x0E
#define PICMG_GET_PORT_STATE_CMD 0x0F
#define PICMG_COMPUTE_POWER_PROPERTIES_CMD 0x10
#define PICMG_SET_POWER_LEVEL_CMD 0x11
#define PICMG_GET_POWER_LEVEL_CMD 0x12
#define PICMG_RENEGOTIATE_POWER_CMD 0x13
#define PICMG_GET_FAN_SPEED_PROPERTIES_CMD 0x14
#define PICMG_SET_FAN_LEVEL_CMD 0x15
#define PICMG_GET_FAN_LEVEL_CMD 0x16
#define PICMG_BUSED_RESOURCE_CMD 0x17
/* Site Types */
#define PICMG_ATCA_BOARD 0x00
#define PICMG_POWER_ENTRY 0x01
#define PICMG_SHELF_FRU 0x02
#define PICMG_DEDICATED_SHMC 0x03
#define PICMG_FAN_TRAY 0x04
#define PICMG_FAN_FILTER_TRAY 0x05
#define PICMG_ALARM 0x06
#define PICMG_AMC 0x07
#define PICMG_PMC 0x08
#define PICMG_RTM 0x09
struct picmg_set_fru_activation_cmd {
unsigned char picmg_id; /* always 0*/
unsigned char fru_id; /* threshold setting mask */
unsigned char fru_state; /* fru activation/deactivation */
} __attribute__ ((packed));
/* the LED color capabilities */
static unsigned char* led_color_str[] = {
"reserved",
"BLUE",
"RED",
"GREEN",
"AMBER",
"ORANGE",
"WHITE",
"reserved"
};
int ipmi_picmg_main (struct ipmi_intf * intf, int argc, char ** argv);
#endif

View File

@ -40,5 +40,7 @@
#include <ipmitool/ipmi.h> #include <ipmitool/ipmi.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 * ipmi_master_write_read(struct ipmi_intf * intf, uint8_t addr, uint8_t * wdata, uint8_t wsize, uint8_t rsize);
int ipmi_rawi2c_main(struct ipmi_intf * intf, int argc, char ** argv);
#endif /* IPMI_RAW_H */ #endif /* IPMI_RAW_H */

View File

@ -48,27 +48,41 @@
#include <ipmitool/ipmi_entity.h> #include <ipmitool/ipmi_entity.h>
int ipmi_sdr_main(struct ipmi_intf *, int, char **); int ipmi_sdr_main(struct ipmi_intf *, int, char **);
int32_t utos(uint32_t val, int bits);
#define tos32(val, bits) ((val & ((1<<((bits)-1)))) ? (-((val) & (1<<((bits)-1))) | (val)) : (val))
#if WORDS_BIGENDIAN #if WORDS_BIGENDIAN
# define __TO_TOL(mtol) (uint16_t)(mtol & 0x3f) # define __TO_TOL(mtol) (uint16_t)(mtol & 0x3f)
# define __TO_M(mtol) (int16_t)(utos((((mtol & 0xff00) >> 8) | ((mtol & 0xc0) << 2)), 10)) # define __TO_M(mtol) (int16_t)(tos32((((mtol & 0xff00) >> 8) | ((mtol & 0xc0) << 2)), 10))
# define __TO_B(bacc) (int32_t)(utos((((bacc & 0xff000000) >> 24) | ((bacc & 0xc00000) >> 14)), 10)) # define __TO_B(bacc) (int32_t)(tos32((((bacc & 0xff000000) >> 24) | ((bacc & 0xc00000) >> 14)), 10))
# define __TO_ACC(bacc) (uint32_t)(((bacc & 0x3f0000) >> 16) | ((bacc & 0xf000) >> 6)) # define __TO_ACC(bacc) (uint32_t)(((bacc & 0x3f0000) >> 16) | ((bacc & 0xf000) >> 6))
# define __TO_ACC_EXP(bacc) (uint32_t)((bacc & 0xc00) >> 10) # define __TO_ACC_EXP(bacc) (uint32_t)((bacc & 0xc00) >> 10)
# define __TO_R_EXP(bacc) (int32_t)(utos(((bacc & 0xf0) >> 4), 4)) # define __TO_R_EXP(bacc) (int32_t)(tos32(((bacc & 0xf0) >> 4), 4))
# define __TO_B_EXP(bacc) (int32_t)(utos((bacc & 0xf), 4)) # define __TO_B_EXP(bacc) (int32_t)(tos32((bacc & 0xf), 4))
#else #else
# define __TO_TOL(mtol) (uint16_t)(BSWAP_16(mtol) & 0x3f) # 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_M(mtol) (int16_t)(tos32((((BSWAP_16(mtol) & 0xff00) >> 8) | ((BSWAP_16(mtol) & 0xc0) << 2)), 10))
# define __TO_B(bacc) (int32_t)(utos((((BSWAP_32(bacc) & 0xff000000) >> 24) | \ # define __TO_B(bacc) (int32_t)(tos32((((BSWAP_32(bacc) & 0xff000000) >> 24) | \
((BSWAP_32(bacc) & 0xc00000) >> 14)), 10)) ((BSWAP_32(bacc) & 0xc00000) >> 14)), 10))
# define __TO_ACC(bacc) (uint32_t)(((BSWAP_32(bacc) & 0x3f0000) >> 16) | ((BSWAP_32(bacc) & 0xf000) >> 6)) # define __TO_ACC(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_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_R_EXP(bacc) (int32_t)(tos32(((BSWAP_32(bacc) & 0xf0) >> 4), 4))
# define __TO_B_EXP(bacc) (int32_t)(utos((BSWAP_32(bacc) & 0xf), 4)) # define __TO_B_EXP(bacc) (int32_t)(tos32((BSWAP_32(bacc) & 0xf), 4))
#endif #endif
enum {
ANALOG_SENSOR,
DISCRETE_SENSOR,
};
#define READING_UNAVAILABLE 0x20
#define SCANNING_DISABLED 0x40
#define EVENT_MSG_DISABLED 0x80
#define IS_READING_UNAVAILABLE(val) ((val) & READING_UNAVAILABLE)
#define IS_SCANNING_DISABLED(val) (!((val) & SCANNING_DISABLED))
#define IS_EVENT_MSG_DISABLED(val) (!((val) & EVENT_MSG_DISABLED))
#define GET_SDR_REPO_INFO 0x20 #define GET_SDR_REPO_INFO 0x20
#define GET_SDR_ALLOC_INFO 0x21 #define GET_SDR_ALLOC_INFO 0x21
@ -79,6 +93,22 @@ int32_t utos(uint32_t val, int bits);
#define SDR_SENSOR_STAT_HI_CR (1<<4) #define SDR_SENSOR_STAT_HI_CR (1<<4)
#define SDR_SENSOR_STAT_HI_NR (1<<5) #define SDR_SENSOR_STAT_HI_NR (1<<5)
#define GET_DEVICE_SDR_INFO 0x20
#define GET_DEVICE_SDR 0x21
#define GET_SENSOR_FACTORS 0x23
#define GET_SENSOR_FACTORS 0x23
#define SET_SENSOR_HYSTERESIS 0x24
#define GET_SENSOR_HYSTERESIS 0x25
#define SET_SENSOR_THRESHOLDS 0x26
#define GET_SENSOR_THRESHOLDS 0x27
#define SET_SENSOR_EVENT_ENABLE 0x28
#define GET_SENSOR_EVENT_ENABLE 0x29
#define GET_SENSOR_EVENT_STATUS 0x2b
#define GET_SENSOR_READING 0x2d
#define GET_SENSOR_TYPE 0x2f
#define GET_SENSOR_READING 0x2d
#define GET_SENSOR_TYPE 0x2f
struct sdr_repo_info_rs { struct sdr_repo_info_rs {
uint8_t version; /* SDR version (51h) */ uint8_t version; /* SDR version (51h) */
uint16_t count; /* number of records */ uint16_t count; /* number of records */
@ -88,6 +118,13 @@ struct sdr_repo_info_rs {
uint8_t op_support; /* supported operations */ uint8_t op_support; /* supported operations */
} __attribute__ ((packed)); } __attribute__ ((packed));
/* builtin (device) sdrs support */
struct sdr_device_info_rs {
unsigned char count; /* number of records */
unsigned char flags; /* flags */
unsigned char popChangeInd[3]; /* free space in SDR */
} __attribute__ ((packed));
#define GET_SDR_RESERVE_REPO 0x22 #define GET_SDR_RESERVE_REPO 0x22
struct sdr_reserve_repo_rs { struct sdr_reserve_repo_rs {
uint16_t reserve_id; /* reservation ID */ uint16_t reserve_id; /* reservation ID */
@ -121,6 +158,126 @@ struct sdr_get_rs {
uint8_t length; /* remaining record bytes */ uint8_t length; /* remaining record bytes */
} __attribute__ ((packed)); } __attribute__ ((packed));
struct sdr_record_mask {
union {
struct {
uint16_t assert_event; /* assertion event mask */
uint16_t deassert_event; /* de-assertion event mask */
uint16_t read; /* discrete reaading mask */
} discrete;
struct {
#if WORDS_BIGENDIAN
uint16_t reserved:1;
uint16_t status_lnr:1;
uint16_t status_lcr:1;
uint16_t status_lnc:1;
uint16_t assert_unr_high:1;
uint16_t assert_unr_low:1;
uint16_t assert_ucr_high:1;
uint16_t assert_ucr_low:1;
uint16_t assert_unc_high:1;
uint16_t assert_unc_low:1;
uint16_t assert_lnr_high:1;
uint16_t assert_lnr_low:1;
uint16_t assert_lcr_high:1;
uint16_t assert_lcr_low:1;
uint16_t assert_lnc_high:1;
uint16_t assert_lnc_low:1;
#else
uint16_t assert_lnc_low:1;
uint16_t assert_lnc_high:1;
uint16_t assert_lcr_low:1;
uint16_t assert_lcr_high:1;
uint16_t assert_lnr_low:1;
uint16_t assert_lnr_high:1;
uint16_t assert_unc_low:1;
uint16_t assert_unc_high:1;
uint16_t assert_ucr_low:1;
uint16_t assert_ucr_high:1;
uint16_t assert_unr_low:1;
uint16_t assert_unr_high:1;
uint16_t status_lnc:1;
uint16_t status_lcr:1;
uint16_t status_lnr:1;
uint16_t reserved:1;
#endif
#if WORDS_BIGENDIAN
uint16_t reserved_2:1;
uint16_t status_unr:1;
uint16_t status_ucr:1;
uint16_t status_unc:1;
uint16_t deassert_unr_high:1;
uint16_t deassert_unr_low:1;
uint16_t deassert_ucr_high:1;
uint16_t deassert_ucr_low:1;
uint16_t deassert_unc_high:1;
uint16_t deassert_unc_low:1;
uint16_t deassert_lnr_high:1;
uint16_t deassert_lnr_low:1;
uint16_t deassert_lcr_high:1;
uint16_t deassert_lcr_low:1;
uint16_t deassert_lnc_high:1;
uint16_t deassert_lnc_low:1;
#else
uint16_t deassert_lnc_low:1;
uint16_t deassert_lnc_high:1;
uint16_t deassert_lcr_low:1;
uint16_t deassert_lcr_high:1;
uint16_t deassert_lnr_low:1;
uint16_t deassert_lnr_high:1;
uint16_t deassert_unc_low:1;
uint16_t deassert_unc_high:1;
uint16_t deassert_ucr_low:1;
uint16_t deassert_ucr_high:1;
uint16_t deassert_unr_low:1;
uint16_t deassert_unr_high:1;
uint16_t status_unc:1;
uint16_t status_ucr:1;
uint16_t status_unr:1;
uint16_t reserved_2:1;
#endif
struct {
#if WORDS_BIGENDIAN /* settable threshold mask */
uint8_t reserved:2;
uint8_t unr:1;
uint8_t ucr:1;
uint8_t unc:1;
uint8_t lnr:1;
uint8_t lcr:1;
uint8_t lnc:1;
#else
uint8_t lnc:1;
uint8_t lcr:1;
uint8_t lnr:1;
uint8_t unc:1;
uint8_t ucr:1;
uint8_t unr:1;
uint8_t reserved:2;
#endif
} set;
struct {
#if WORDS_BIGENDIAN /* readable threshold mask */
uint8_t reserved:2;
uint8_t unr:1;
uint8_t ucr:1;
uint8_t unc:1;
uint8_t lnr:1;
uint8_t lcr:1;
uint8_t lnc:1;
#else
uint8_t lnc:1;
uint8_t lcr:1;
uint8_t lnr:1;
uint8_t unc:1;
uint8_t ucr:1;
uint8_t unr:1;
uint8_t reserved:2;
#endif
} read;
} threshold;
} type;
} __attribute__ ((packed));
struct sdr_record_compact_sensor { struct sdr_record_compact_sensor {
struct { struct {
uint8_t owner_id; uint8_t owner_id;
@ -180,19 +337,7 @@ struct sdr_record_compact_sensor {
uint8_t event_type; /* event/reading type code */ uint8_t event_type; /* event/reading type code */
union { struct sdr_record_mask mask;
struct {
uint16_t assert_event; /* assertion event mask */
uint16_t deassert_event; /* de-assertion event mask */
uint16_t read; /* discrete reaading mask */
} discrete;
struct {
uint16_t lower; /* lower threshold reading mask */
uint16_t upper; /* upper threshold reading mask */
uint8_t set; /* settable threshold mask */
uint8_t read; /* readable threshold mask */
} threshold;
} mask;
struct { struct {
#if WORDS_BIGENDIAN #if WORDS_BIGENDIAN
@ -349,19 +494,7 @@ struct sdr_record_full_sensor {
uint8_t event_type; /* event/reading type code */ uint8_t event_type; /* event/reading type code */
union { struct sdr_record_mask mask;
struct {
uint16_t assert_event; /* assertion event mask */
uint16_t deassert_event; /* de-assertion event mask */
uint16_t read; /* discrete reaading mask */
} discrete;
struct {
uint16_t lower; /* lower threshold reading mask */
uint16_t upper; /* upper threshold reading mask */
uint8_t set; /* settable threshold mask */
uint8_t read; /* readable threshold mask */
} threshold;
} mask;
struct { struct {
#if WORDS_BIGENDIAN #if WORDS_BIGENDIAN
@ -381,6 +514,20 @@ struct sdr_record_full_sensor {
} type; } type;
} unit; } unit;
#define SDR_SENSOR_L_LINEAR 0x00
#define SDR_SENSOR_L_LN 0x01
#define SDR_SENSOR_L_LOG10 0x02
#define SDR_SENSOR_L_LOG2 0x03
#define SDR_SENSOR_L_E 0x04
#define SDR_SENSOR_L_EXP10 0x05
#define SDR_SENSOR_L_EXP2 0x06
#define SDR_SENSOR_L_1_X 0x07
#define SDR_SENSOR_L_SQR 0x08
#define SDR_SENSOR_L_CUBE 0x09
#define SDR_SENSOR_L_SQRT 0x0a
#define SDR_SENSOR_L_CUBERT 0x0b
#define SDR_SENSOR_L_NONLINEAR 0x70
uint8_t linearization; /* 70h=non linear, 71h-7Fh=non linear, OEM */ uint8_t linearization; /* 70h=non linear, 71h-7Fh=non linear, OEM */
uint16_t mtol; /* M, tolerance */ uint16_t mtol; /* M, tolerance */
uint32_t bacc; /* accuracy, B, Bexp, Rexp */ uint32_t bacc; /* accuracy, B, Bexp, Rexp */
@ -457,22 +604,22 @@ struct sdr_record_fru_locator {
uint8_t dev_slave_addr; uint8_t dev_slave_addr;
uint8_t device_id; uint8_t device_id;
#if WORDS_BIGENDIAN #if WORDS_BIGENDIAN
uint8_t bus : 3;
uint8_t lun : 2;
uint8_t __reserved2 : 2;
uint8_t logical:1; uint8_t logical:1;
uint8_t __reserved2:2;
uint8_t lun:2;
uint8_t bus:3;
#else #else
uint8_t logical : 1;
uint8_t __reserved2 : 2;
uint8_t lun : 2;
uint8_t bus:3; uint8_t bus:3;
uint8_t lun:2;
uint8_t __reserved2:2;
uint8_t logical:1;
#endif #endif
#if WORDS_BIGENDIAN #if WORDS_BIGENDIAN
uint8_t __reserved3 : 4;
uint8_t channel_num:4; uint8_t channel_num:4;
uint8_t __reserved3:4;
#else #else
uint8_t channel_num : 4;
uint8_t __reserved3:4; uint8_t __reserved3:4;
uint8_t channel_num:4;
#endif #endif
uint8_t __reserved4; uint8_t __reserved4;
uint8_t dev_type; uint8_t dev_type;
@ -483,6 +630,59 @@ struct sdr_record_fru_locator {
uint8_t id_string[16]; uint8_t id_string[16];
} __attribute__ ((packed)); } __attribute__ ((packed));
struct sdr_record_generic_locator {
uint8_t dev_access_addr;
uint8_t dev_slave_addr;
#if WORDS_BIGENDIAN
uint8_t channel_num:3;
uint8_t lun:2;
uint8_t bus:3;
#else
uint8_t bus:3;
uint8_t lun:2;
uint8_t channel_num:3;
#endif
#if WORDS_BIGENDIAN
uint8_t addr_span:3;
uint8_t __reserved1:5;
#else
uint8_t __reserved1:5;
uint8_t addr_span:3;
#endif
uint8_t __reserved2;
uint8_t dev_type;
uint8_t dev_type_modifier;
struct entity_id entity;
uint8_t oem;
uint8_t id_code;
uint8_t id_string[16];
} __attribute__ ((packed));
struct sdr_record_entity_assoc {
struct entity_id entity; /* container entity ID and instance */
struct {
#if WORDS_BIGENDIAN
uint8_t isrange:1;
uint8_t islinked:1;
uint8_t isaccessable:1;
uint8_t __reserved:5;
#else
uint8_t __reserved:5;
uint8_t isaccessable:1;
uint8_t islinked:1;
uint8_t isrange:1;
#endif
} flags;
uint8_t entity_id_1; /* entity ID 1 | range 1 entity */
uint8_t entity_inst_1; /* entity inst 1 | range 1 first instance */
uint8_t entity_id_2; /* entity ID 2 | range 1 entity */
uint8_t entity_inst_2; /* entity inst 2 | range 1 last instance */
uint8_t entity_id_3; /* entity ID 3 | range 2 entity */
uint8_t entity_inst_3; /* entity inst 3 | range 2 first instance */
uint8_t entity_id_4; /* entity ID 4 | range 2 entity */
uint8_t entity_inst_4; /* entity inst 4 | range 2 last instance */
} __attribute__ ((packed));
struct sdr_record_oem { struct sdr_record_oem {
uint8_t *data; uint8_t *data;
int data_len; int data_len;
@ -518,11 +718,7 @@ struct get_sdr_repository_info_rsp {
#endif #endif
} __attribute__ ((packed)); } __attribute__ ((packed));
struct ipmi_sdr_iterator {
struct ipmi_sdr_iterator
{
uint16_t reservation; uint16_t reservation;
int total; int total;
int next; int next;
@ -536,8 +732,10 @@ struct sdr_record_list {
struct sdr_record_full_sensor *full; struct sdr_record_full_sensor *full;
struct sdr_record_compact_sensor *compact; struct sdr_record_compact_sensor *compact;
struct sdr_record_eventonly_sensor *eventonly; struct sdr_record_eventonly_sensor *eventonly;
struct sdr_record_generic_locator *genloc;
struct sdr_record_fru_locator *fruloc; struct sdr_record_fru_locator *fruloc;
struct sdr_record_mc_locator *mcloc; struct sdr_record_mc_locator *mcloc;
struct sdr_record_entity_assoc *entassoc;
struct sdr_record_oem *oem; struct sdr_record_oem *oem;
} record; } record;
}; };
@ -552,63 +750,109 @@ static const char * unit_desc[] __attribute__((unused)) = {
"lumen", "lux", "Candela", "lumen", "lux", "Candela",
"kPa", "PSI", "Newton", "kPa", "PSI", "Newton",
"CFM", "RPM", "Hz", "CFM", "RPM", "Hz",
"microsecond", "millisecond", "second", "minute", "hour", "day", "week", "microsecond", "millisecond", "second", "minute", "hour",
"mil", "inches", "feet", "cu in", "cu feet", "mm", "cm", "m", "cu cm", "cu m", "day", "week", "mil", "inches", "feet", "cu in", "cu feet",
"liters", "fluid ounce", "mm", "cm", "m", "cu cm", "cu m", "liters", "fluid ounce",
"radians", "steradians", "revolutions", "cycles", "gravities", "radians", "steradians", "revolutions", "cycles",
"ounce", "pound", "ft-lb", "oz-in", "gravities", "ounce", "pound", "ft-lb", "oz-in", "gauss",
"gauss", "gilberts", "henry", "millihenry", "gilberts", "henry", "millihenry", "farad", "microfarad",
"farad", "microfarad", "ohms", "siemens", "mole", "becquerel", "ohms", "siemens", "mole", "becquerel", "PPM", "reserved",
"PPM", "reserved", "Decibels", "DbA", "DbC", "gray", "sievert",
"Decibels", "DbA", "DbC", "color temp deg K", "bit", "kilobit", "megabit", "gigabit",
"gray", "sievert", "color temp deg K", "byte", "kilobyte", "megabyte", "gigabyte", "word", "dword",
"bit", "kilobit", "megabit", "gigabit", "qword", "line", "hit", "miss", "retry", "reset",
"byte", "kilobyte", "megabyte", "gigabyte", "overflow", "underrun", "collision", "packets", "messages",
"word", "dword", "qword", "line", "characters", "error", "correctable error", "uncorrectable error",};
"hit", "miss", "retry", "reset",
"overflow", "underrun",
"collision", "packets",
"messages", "characters",
"error", "correctable error", "uncorrectable error",
};
/* sensor type codes (IPMI v1.5 table 36.3) */ /* sensor type codes (IPMI v1.5 table 36.3) */
#define SENSOR_TYPE_MAX 0x29 #define SENSOR_TYPE_MAX 0x29
static const char *sensor_type_desc[] __attribute__ ((unused)) = { static const char *sensor_type_desc[] __attribute__ ((unused)) = {
"reserved", "reserved",
"Temperature", "Voltage", "Current", "Fan", "Physical Security", "Platform Security Violation Attempt", "Temperature", "Voltage", "Current", "Fan",
"Processor", "Power Supply", "Power Unit", "Cooling Device", "Other", "Memory", "Drive Slot / Bay", "Physical Security", "Platform Security", "Processor",
"POST Memory Resize", "System Firmware Progress", "Event Logging Disabled", "Watchdog", "System Event", "Power Supply", "Power Unit", "Cooling Device", "Other",
"Critical Interrupt", "Button", "Module / Board", "Microcontroller / Coprocessor", "Add-in Card", "Memory", "Drive Slot / Bay", "POST Memory Resize",
"Chassis", "Chip Set", "Other FRU", "Cable / Interconnect", "Terminator", "System Boot Initiated", "System Firmwares", "Event Logging Disabled", "Watchdog",
"Boot Error", "OS Boot", "OS Critical Stop", "Slot / Connector", "System ACPI Power State", "Watchdog", "System Event", "Critical Interrupt", "Button",
"Platform Alert", "Entity Presence", "Monitor ASIC / IC", "LAN", "Management Subsystem Health", "Battery" "Module / Board", "Microcontroller", "Add-in Card",
}; "Chassis", "Chip Set", "Other FRU", "Cable / Interconnect",
"Terminator", "System Boot Initiated", "Boot Error",
"OS Boot", "OS Critical Stop", "Slot / Connector",
"System ACPI Power State", "Watchdog", "Platform Alert",
"Entity Presence", "Monitor ASIC", "LAN",
"Management Subsystem Health", "Battery"};
struct ipmi_sdr_iterator *ipmi_sdr_start(struct ipmi_intf *intf); struct 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); struct sdr_get_rs *ipmi_sdr_get_next_header(struct ipmi_intf *intf,
uint8_t * ipmi_sdr_get_record(struct ipmi_intf * intf, struct sdr_get_rs * header, struct ipmi_sdr_iterator * i); 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_end(struct ipmi_intf *intf, struct ipmi_sdr_iterator *i);
int ipmi_sdr_print_sdr(struct ipmi_intf *intf, uint8_t type); int ipmi_sdr_print_sdr(struct ipmi_intf *intf, uint8_t type);
int ipmi_sdr_print_rawentry(struct ipmi_intf * intf, uint8_t type, uint8_t * raw, int len); int ipmi_sdr_print_rawentry(struct ipmi_intf *intf, uint8_t type, uint8_t * raw,
int ipmi_sdr_print_listentry(struct ipmi_intf * intf, struct sdr_record_list * entry); int len);
const char * ipmi_sdr_get_status(uint8_t stat); int ipmi_sdr_print_listentry(struct ipmi_intf *intf,
float sdr_convert_sensor_reading(struct sdr_record_full_sensor * sensor, uint8_t val); struct sdr_record_list *entry);
uint8_t sdr_convert_sensor_value_to_raw(struct sdr_record_full_sensor * sensor, float val); char *ipmi_sdr_get_unit_string(uint8_t type, uint8_t base, uint8_t modifier);
struct ipmi_rs * ipmi_sdr_get_sensor_reading(struct ipmi_intf * intf, uint8_t sensor); const char *ipmi_sdr_get_status(struct sdr_record_full_sensor *sensor,
uint8_t stat);
double sdr_convert_sensor_reading(struct sdr_record_full_sensor *sensor,
uint8_t val);
uint8_t sdr_convert_sensor_value_to_raw(struct sdr_record_full_sensor *sensor,
double val);
struct ipmi_rs *ipmi_sdr_get_sensor_reading(struct ipmi_intf *intf,
uint8_t sensor);
struct ipmi_rs *ipmi_sdr_get_sensor_reading_ipmb(struct ipmi_intf *intf,
uint8_t sensor,
uint8_t target);
struct ipmi_rs *ipmi_sdr_get_sensor_thresholds(struct ipmi_intf *intf,
uint8_t sensor);
struct ipmi_rs *ipmi_sdr_get_sensor_hysteresis(struct ipmi_intf *intf,
uint8_t sensor);
const char *ipmi_sdr_get_sensor_type_desc(const uint8_t type); const char *ipmi_sdr_get_sensor_type_desc(const uint8_t type);
int ipmi_sdr_get_reservation(struct ipmi_intf *intf, uint16_t * reserve_id);
int ipmi_sdr_print_sensor_full(struct ipmi_intf * intf, struct sdr_record_full_sensor * sensor); int ipmi_sdr_print_sensor_full(struct ipmi_intf *intf,
int ipmi_sdr_print_sensor_compact(struct ipmi_intf * intf, struct sdr_record_compact_sensor * sensor); struct sdr_record_full_sensor *sensor);
int ipmi_sdr_print_sensor_eventonly(struct ipmi_intf * intf, struct sdr_record_eventonly_sensor * sensor); int ipmi_sdr_print_sensor_compact(struct ipmi_intf *intf,
int ipmi_sdr_print_sensor_fru_locator(struct ipmi_intf * intf, struct sdr_record_fru_locator * fru); struct sdr_record_compact_sensor *sensor);
int ipmi_sdr_print_sensor_mc_locator(struct ipmi_intf * intf, struct sdr_record_mc_locator * mc); int ipmi_sdr_print_sensor_eventonly(struct ipmi_intf *intf,
struct sdr_record_eventonly_sensor *sensor);
int ipmi_sdr_print_sensor_generic_locator(struct ipmi_intf *intf,
struct sdr_record_generic_locator
*fru);
int ipmi_sdr_print_sensor_fru_locator(struct ipmi_intf *intf,
struct sdr_record_fru_locator *fru);
int ipmi_sdr_print_sensor_mc_locator(struct ipmi_intf *intf,
struct sdr_record_mc_locator *mc);
int ipmi_sdr_print_sensor_entity_assoc(struct ipmi_intf *intf,
struct sdr_record_entity_assoc *assoc);
struct sdr_record_list * ipmi_sdr_find_sdr_byentity(struct ipmi_intf * intf, struct entity_id * entity); struct sdr_record_list *ipmi_sdr_find_sdr_byentity(struct ipmi_intf *intf,
struct sdr_record_list * ipmi_sdr_find_sdr_bynumtype(struct ipmi_intf * intf, uint8_t num, uint8_t type); struct entity_id *entity);
struct sdr_record_list * ipmi_sdr_find_sdr_byid(struct ipmi_intf * intf, char * id); struct sdr_record_list *ipmi_sdr_find_sdr_bynumtype(struct ipmi_intf *intf,
uint8_t num, uint8_t type);
struct sdr_record_list *ipmi_sdr_find_sdr_bysensortype(struct ipmi_intf *intf,
uint8_t type);
struct sdr_record_list *ipmi_sdr_find_sdr_byid(struct ipmi_intf *intf,
char *id);
struct sdr_record_list *ipmi_sdr_find_sdr_bytype(struct ipmi_intf *intf,
uint8_t type);
int ipmi_sdr_list_cache(struct ipmi_intf *intf);
int ipmi_sdr_list_cache_fromfile(struct ipmi_intf *intf, const char *ifile);
void ipmi_sdr_list_empty(struct ipmi_intf *intf); void ipmi_sdr_list_empty(struct ipmi_intf *intf);
int ipmi_sdr_print_info(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); void ipmi_sdr_print_discrete_state(const char *desc, uint8_t sensor_type,
uint8_t event_type, uint8_t state1,
uint8_t state2);
void ipmi_sdr_print_discrete_state_mini(const char *separator,
uint8_t sensor_type, uint8_t event_type,
uint8_t state1, uint8_t state2);
int ipmi_sdr_print_sensor_event_status(struct ipmi_intf *intf,
uint8_t sensor_num, uint8_t sensor_type,
uint8_t event_type, int numeric_fmt);
int ipmi_sdr_print_sensor_event_enable(struct ipmi_intf *intf,
uint8_t sensor_num, uint8_t sensor_type,
uint8_t event_type, int numeric_fmt);
#endif /* IPMI_SDR_H */ #endif /* IPMI_SDR_H */

View File

@ -39,6 +39,7 @@
#include <inttypes.h> #include <inttypes.h>
#include <ipmitool/ipmi.h> #include <ipmitool/ipmi.h>
#include <ipmitool/ipmi_sdr.h>
#define IPMI_CMD_GET_SEL_INFO 0x40 #define IPMI_CMD_GET_SEL_INFO 0x40
#define IPMI_CMD_GET_SEL_ALLOC_INFO 0x41 #define IPMI_CMD_GET_SEL_ALLOC_INFO 0x41
@ -67,36 +68,45 @@ struct sel_get_rq {
uint8_t length; uint8_t length;
} __attribute__ ((packed)); } __attribute__ ((packed));
struct sel_event_record { struct standard_spec_sel_rec{
uint16_t record_id;
uint8_t record_type;
uint32_t timestamp; uint32_t timestamp;
uint16_t gen_id; uint16_t gen_id;
uint8_t evm_rev; uint8_t evm_rev;
uint8_t sensor_type; uint8_t sensor_type;
uint8_t sensor_num; uint8_t sensor_num;
#if WORDS_BIGENDIAN
uint8_t event_dir : 1;
uint8_t event_type : 7;
#else
uint8_t event_type : 7; uint8_t event_type : 7;
uint8_t event_dir : 1; uint8_t event_dir : 1;
#endif
#define DATA_BYTE2_SPECIFIED_MASK 0xc0 /* event_data[0] bit mask */ #define DATA_BYTE2_SPECIFIED_MASK 0xc0 /* event_data[0] bit mask */
#define DATA_BYTE3_SPECIFIED_MASK 0x30 /* 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 */ #define EVENT_OFFSET_MASK 0x0f /* event_data[0] bit mask */
uint8_t event_data[3]; uint8_t event_data[3];
} __attribute__ ((packed)); };
struct sel_oem_record_ts { #define SEL_OEM_TS_DATA_LEN 6
uint16_t next_id; #define SEL_OEM_NOTS_DATA_LEN 13
uint16_t record_id; struct oem_ts_spec_sel_rec{
uint8_t record_type;
uint32_t timestamp; uint32_t timestamp;
uint8_t mfg_id[3]; uint8_t manf_id[3];
uint8_t oem_defined[6]; uint8_t oem_defined[SEL_OEM_TS_DATA_LEN];
} __attribute__ ((packed)); };
struct sel_oem_record_nots { struct oem_nots_spec_sel_rec{
uint16_t next_id; uint8_t oem_defined[SEL_OEM_NOTS_DATA_LEN];
};
struct sel_event_record {
uint16_t record_id; uint16_t record_id;
uint8_t record_type; uint8_t record_type;
uint8_t oem_defined[13]; union{
struct standard_spec_sel_rec standard_type;
struct oem_ts_spec_sel_rec oem_ts_type;
struct oem_nots_spec_sel_rec oem_nots_type;
} sel_type;
} __attribute__ ((packed)); } __attribute__ ((packed));
struct ipmi_event_sensor_types { struct ipmi_event_sensor_types {
@ -111,18 +121,18 @@ struct ipmi_event_sensor_types {
static struct ipmi_event_sensor_types generic_event_types[] __attribute__((unused)) = { static struct ipmi_event_sensor_types generic_event_types[] __attribute__((unused)) = {
/* Threshold Based States */ /* Threshold Based States */
{ 0x01, 0x00, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Lower Non-critical - going low" }, { 0x01, 0x00, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Lower Non-critical going low " },
{ 0x01, 0x01, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Lower Non-critical - going high" }, { 0x01, 0x01, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Lower Non-critical going high" },
{ 0x01, 0x02, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Lower Critical - going low" }, { 0x01, 0x02, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Lower Critical going low " },
{ 0x01, 0x03, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Lower Critical - going high" }, { 0x01, 0x03, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Lower Critical going high" },
{ 0x01, 0x04, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Lower Non-recoverable - going low" }, { 0x01, 0x04, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Lower Non-recoverable going low " },
{ 0x01, 0x05, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Lower Non-recoverable - going high" }, { 0x01, 0x05, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Lower Non-recoverable going high" },
{ 0x01, 0x06, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Upper Non-critical - going low" }, { 0x01, 0x06, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Upper Non-critical going low " },
{ 0x01, 0x07, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Upper Non-critical - going high" }, { 0x01, 0x07, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Upper Non-critical going high" },
{ 0x01, 0x08, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Upper Critical - going low" }, { 0x01, 0x08, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Upper Critical going low " },
{ 0x01, 0x09, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Upper Critical - going high" }, { 0x01, 0x09, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Upper Critical going high" },
{ 0x01, 0x0a, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Upper Non-recoverable - going low" }, { 0x01, 0x0a, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Upper Non-recoverable going low " },
{ 0x01, 0x0b, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Upper Non-recoverable - going high" }, { 0x01, 0x0b, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Upper Non-recoverable going high" },
/* DMI-based "usage state" States */ /* DMI-based "usage state" States */
{ 0x02, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Usage State", "Transition to Idle" }, { 0x02, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Usage State", "Transition to Idle" },
{ 0x02, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Usage State", "Transition to Active" }, { 0x02, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Usage State", "Transition to Active" },
@ -147,8 +157,8 @@ static struct ipmi_event_sensor_types generic_event_types[] __attribute__((unuse
{ 0x07, 0x07, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Severity State", "Monitor" }, { 0x07, 0x07, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Severity State", "Monitor" },
{ 0x07, 0x08, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Severity State", "Informational" }, { 0x07, 0x08, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Severity State", "Informational" },
/* Availability Status States */ /* Availability Status States */
{ 0x08, 0x00, 0xff, IPMI_EVENT_CLASS_DIGITAL, "Availability State", "Device Removed/Absent" }, { 0x08, 0x00, 0xff, IPMI_EVENT_CLASS_DIGITAL, "Availability State", "Device Absent" },
{ 0x08, 0x01, 0xff, IPMI_EVENT_CLASS_DIGITAL, "Availability State", "Device Inserted/Present" }, { 0x08, 0x01, 0xff, IPMI_EVENT_CLASS_DIGITAL, "Availability State", "Device Present" },
{ 0x09, 0x00, 0xff, IPMI_EVENT_CLASS_DIGITAL, "Availability State", "Device Disabled" }, { 0x09, 0x00, 0xff, IPMI_EVENT_CLASS_DIGITAL, "Availability State", "Device Disabled" },
{ 0x09, 0x01, 0xff, IPMI_EVENT_CLASS_DIGITAL, "Availability State", "Device Enabled" }, { 0x09, 0x01, 0xff, IPMI_EVENT_CLASS_DIGITAL, "Availability State", "Device Enabled" },
{ 0x0a, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Availability State", "Transition to Running" }, { 0x0a, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Availability State", "Transition to Running" },
@ -190,7 +200,7 @@ static struct ipmi_event_sensor_types sensor_specific_types[] __attribute__((unu
{ 0x05, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Physical Security", "I/O Card area intrusion" }, { 0x05, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Physical Security", "I/O Card area intrusion" },
{ 0x05, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Physical Security", "Processor area intrusion" }, { 0x05, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Physical Security", "Processor area intrusion" },
{ 0x05, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Physical Security", "System unplugged from LAN" }, { 0x05, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Physical Security", "System unplugged from LAN" },
{ 0x05, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Physical Security", "Unauthorized dock/undock" }, { 0x05, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Physical Security", "Unauthorized dock" },
{ 0x05, 0x06, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Physical Security", "FAN area intrusion" }, { 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, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Platform Security", "Front Panel Lockout violation attempted" },
@ -210,6 +220,7 @@ static struct ipmi_event_sensor_types sensor_specific_types[] __attribute__((unu
{ 0x07, 0x07, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Processor", "Presence detected" }, { 0x07, 0x07, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Processor", "Presence detected" },
{ 0x07, 0x08, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Processor", "Disabled" }, { 0x07, 0x08, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Processor", "Disabled" },
{ 0x07, 0x09, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Processor", "Terminator presence detected" }, { 0x07, 0x09, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Processor", "Terminator presence detected" },
{ 0x07, 0x0a, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Processor", "Throttled" },
{ 0x08, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Power Supply", "Presence detected" }, { 0x08, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Power Supply", "Presence detected" },
{ 0x08, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Power Supply", "Failure detected" }, { 0x08, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Power Supply", "Failure detected" },
@ -217,6 +228,10 @@ static struct ipmi_event_sensor_types sensor_specific_types[] __attribute__((unu
{ 0x08, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Power Supply", "Power Supply AC lost" }, { 0x08, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Power Supply", "Power Supply AC lost" },
{ 0x08, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Power Supply", "AC lost or out-of-range" }, { 0x08, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Power Supply", "AC lost or out-of-range" },
{ 0x08, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Power Supply", "AC out-of-range, but present" }, { 0x08, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Power Supply", "AC out-of-range, but present" },
{ 0x08, 0x06, 0x00, IPMI_EVENT_CLASS_DISCRETE, "Power Supply", "Config Error: Vendor Mismatch" },
{ 0x08, 0x06, 0x01, IPMI_EVENT_CLASS_DISCRETE, "Power Supply", "Config Error: Revision Mismatch" },
{ 0x08, 0x06, 0x02, IPMI_EVENT_CLASS_DISCRETE, "Power Supply", "Config Error: Processor Missing" },
{ 0x08, 0x06, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Power Supply", "Config Error" },
{ 0x09, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Power Unit", "Power off/down" }, { 0x09, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Power Unit", "Power off/down" },
{ 0x09, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Power Unit", "Power cycle" }, { 0x09, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Power Unit", "Power cycle" },
@ -236,31 +251,108 @@ static struct ipmi_event_sensor_types sensor_specific_types[] __attribute__((unu
{ 0x0c, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Memory", "Memory Scrub Failed" }, { 0x0c, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Memory", "Memory Scrub Failed" },
{ 0x0c, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Memory", "Memory Device Disabled" }, { 0x0c, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Memory", "Memory Device Disabled" },
{ 0x0c, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Memory", "Correctable ECC logging limit reached" }, { 0x0c, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Memory", "Correctable ECC logging limit reached" },
{ 0x0c, 0x06, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Memory", "Presence Detected" },
{ 0x0c, 0x07, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Memory", "Configuration Error" },
{ 0x0c, 0x08, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Memory", "Spare" },
{ 0x0c, 0x09, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Memory", "Throttled" },
{ 0x0d, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Drive Slot", "Drive Present" },
{ 0x0d, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Drive Slot", "Drive Fault" },
{ 0x0d, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Drive Slot", "Predictive Failure" },
{ 0x0d, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Drive Slot", "Hot Spare" },
{ 0x0d, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Drive Slot", "Parity Check In Progress" },
{ 0x0d, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Drive Slot", "In Critical Array" },
{ 0x0d, 0x06, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Drive Slot", "In Failed Array" },
{ 0x0d, 0x07, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Drive Slot", "Rebuild In Progress" },
{ 0x0d, 0x08, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Drive Slot", "Rebuild Aborted" },
{ 0x0d, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Drive Slot", NULL },
{ 0x0e, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "POST Memory Resize", NULL }, { 0x0e, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "POST Memory Resize", NULL },
{ 0x0f, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Firmware", "Error" }, { 0x0f, 0x00, 0x00, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Error", "Unspecified" },
{ 0x0f, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Firmware", "Hang" }, { 0x0f, 0x00, 0x01, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Error", "No system memory installed" },
{ 0x0f, 0x02, 0x00, IPMI_EVENT_CLASS_DISCRETE, "System Firmware", "Progress 1" }, { 0x0f, 0x00, 0x02, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Error", "No usable system memory" },
{ 0x0f, 0x02, 0x01, IPMI_EVENT_CLASS_DISCRETE, "System Firmware", "Progress 2" }, { 0x0f, 0x00, 0x03, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Error", "Unrecoverable IDE device failure" },
{ 0x0f, 0x02, 0x02, IPMI_EVENT_CLASS_DISCRETE, "System Firmware", "Progress 3" }, { 0x0f, 0x00, 0x04, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Error", "Unrecoverable system-board failure" },
{ 0x0f, 0x02, 0x03, IPMI_EVENT_CLASS_DISCRETE, "System Firmware", "Progress 4" }, { 0x0f, 0x00, 0x05, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Error", "Unrecoverable diskette failure" },
{ 0x0f, 0x02, 0x04, IPMI_EVENT_CLASS_DISCRETE, "System Firmware", "Progress 5" }, { 0x0f, 0x00, 0x06, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Error", "Unrecoverable hard-disk controller failure" },
{ 0x0f, 0x02, 0x13, IPMI_EVENT_CLASS_DISCRETE, "System Firmware", "System Boot Initiated" }, { 0x0f, 0x00, 0x07, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Error", "Unrecoverable PS/2 or USB keyboard failure" },
{ 0x0f, 0x00, 0x08, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Error", "Removable boot media not found" },
{ 0x0f, 0x00, 0x09, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Error", "Unrecoverable video controller failure" },
{ 0x0f, 0x00, 0x0a, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Error", "No video device selected" },
{ 0x0f, 0x00, 0x0b, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Error", "BIOS corruption detected" },
{ 0x0f, 0x00, 0x0c, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Error", "CPU voltage mismatch" },
{ 0x0f, 0x00, 0x0d, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Error", "CPU speed mismatch failure" },
{ 0x0f, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Error", "Unknown Error" },
{ 0x0f, 0x01, 0x00, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Unspecified" },
{ 0x0f, 0x01, 0x01, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Memory initialization" },
{ 0x0f, 0x01, 0x02, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Hard-disk initialization" },
{ 0x0f, 0x01, 0x03, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Secondary CPU Initialization" },
{ 0x0f, 0x01, 0x04, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "User authentication" },
{ 0x0f, 0x01, 0x05, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "User-initiated system setup" },
{ 0x0f, 0x01, 0x06, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "USB resource configuration" },
{ 0x0f, 0x01, 0x07, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "PCI resource configuration" },
{ 0x0f, 0x01, 0x08, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Option ROM initialization" },
{ 0x0f, 0x01, 0x09, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Video initialization" },
{ 0x0f, 0x01, 0x0a, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Cache initialization" },
{ 0x0f, 0x01, 0x0b, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "SMBus initialization" },
{ 0x0f, 0x01, 0x0c, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Keyboard controller initialization" },
{ 0x0f, 0x01, 0x0d, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Management controller initialization" },
{ 0x0f, 0x01, 0x0e, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Docking station attachment" },
{ 0x0f, 0x01, 0x0f, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Enabling docking station" },
{ 0x0f, 0x01, 0x10, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Docking station ejection" },
{ 0x0f, 0x01, 0x11, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Disabling docking station" },
{ 0x0f, 0x01, 0x12, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Calling operating system wake-up vector" },
{ 0x0f, 0x01, 0x13, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "System boot initiated" },
{ 0x0f, 0x01, 0x14, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Motherboard initialization" },
{ 0x0f, 0x01, 0x15, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "reserved" },
{ 0x0f, 0x01, 0x16, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Floppy initialization" },
{ 0x0f, 0x01, 0x17, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Keyboard test" },
{ 0x0f, 0x01, 0x18, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Pointing device test" },
{ 0x0f, 0x01, 0x19, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Primary CPU initialization" },
{ 0x0f, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Unknown Hang" },
{ 0x0f, 0x02, 0x00, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Unspecified" },
{ 0x0f, 0x02, 0x01, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Memory initialization" },
{ 0x0f, 0x02, 0x02, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Hard-disk initialization" },
{ 0x0f, 0x02, 0x03, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Secondary CPU Initialization" },
{ 0x0f, 0x02, 0x04, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "User authentication" },
{ 0x0f, 0x02, 0x05, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "User-initiated system setup" },
{ 0x0f, 0x02, 0x06, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "USB resource configuration" },
{ 0x0f, 0x02, 0x07, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "PCI resource configuration" },
{ 0x0f, 0x02, 0x08, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Option ROM initialization" },
{ 0x0f, 0x02, 0x09, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Video initialization" },
{ 0x0f, 0x02, 0x0a, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Cache initialization" },
{ 0x0f, 0x02, 0x0b, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "SMBus initialization" },
{ 0x0f, 0x02, 0x0c, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Keyboard controller initialization" },
{ 0x0f, 0x02, 0x0d, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Management controller initialization" },
{ 0x0f, 0x02, 0x0e, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Docking station attachment" },
{ 0x0f, 0x02, 0x0f, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Enabling docking station" },
{ 0x0f, 0x02, 0x10, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Docking station ejection" },
{ 0x0f, 0x02, 0x11, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Disabling docking station" },
{ 0x0f, 0x02, 0x12, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Calling operating system wake-up vector" },
{ 0x0f, 0x02, 0x13, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "System boot initiated" },
{ 0x0f, 0x02, 0x14, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Motherboard initialization" },
{ 0x0f, 0x02, 0x15, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "reserved" },
{ 0x0f, 0x02, 0x16, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Floppy initialization" },
{ 0x0f, 0x02, 0x17, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Keyboard test" },
{ 0x0f, 0x02, 0x18, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Pointing device test" },
{ 0x0f, 0x02, 0x19, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Primary CPU initialization" },
{ 0x0f, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Unknown Progress" },
{ 0x10, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Event Logging Disabled", "Correctable memory error logging disabled" }, { 0x10, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Event Logging Disabled", "Correctable memory error logging disabled" },
{ 0x10, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Event Logging Disabled", "Event logging disabled" }, { 0x10, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Event Logging Disabled", "Event logging disabled" },
{ 0x10, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Event Logging Disabled", "Log area reset/cleared" }, { 0x10, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Event Logging Disabled", "Log area reset/cleared" },
{ 0x10, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Event Logging Disabled", "All event logging disabled" }, { 0x10, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Event Logging Disabled", "All event logging disabled" },
{ 0x10, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Event Logging Disabled", "Log full" }, { 0x10, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Event Logging Disabled", "Log full" },
{ 0x10, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Event Logging Disabled", "Log almost full" },
{ 0x11, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Watchdog 1", "BIOS Reset" }, { 0x11, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Watchdog 1", "BIOS Reset" },
{ 0x11, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Watchdog 1", "OS Reset" }, { 0x11, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Watchdog 1", "OS Reset" },
{ 0x11, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Watchdog 1", "OS Shut Down" }, { 0x11, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Watchdog 1", "OS Shut Down" },
{ 0x11, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Watchdog 1", "OS Power Down" }, { 0x11, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Watchdog 1", "OS Power Down" },
{ 0x11, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Watchdog 1", "OS Power Cycle" }, { 0x11, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Watchdog 1", "OS Power Cycle" },
{ 0x11, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Watchdog 1", "OS NMI/diag Interrupt" }, { 0x11, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Watchdog 1", "OS NMI/Diag Interrupt" },
{ 0x11, 0x06, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Watchdog 1", "OS Expired" }, { 0x11, 0x06, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Watchdog 1", "OS Expired" },
{ 0x11, 0x07, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Watchdog 1", "OS pre-timeout Interrupt" }, { 0x11, 0x07, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Watchdog 1", "OS pre-timeout Interrupt" },
@ -269,9 +361,9 @@ static struct ipmi_event_sensor_types sensor_specific_types[] __attribute__((unu
{ 0x12, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Event", "Undetermined system hardware failure" }, { 0x12, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Event", "Undetermined system hardware failure" },
{ 0x12, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Event", "Entry added to auxiliary log" }, { 0x12, 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, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Event", "PEF Action" },
{ 0x12, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Event", "Timestamp Clock Sync." }, { 0x12, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Event", "Timestamp Clock Sync" },
{ 0x13, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Critical Interrupt", "Front Panel NMI" }, { 0x13, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Critical Interrupt", "NMI/Diag Interrupt" },
{ 0x13, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Critical Interrupt", "Bus Timeout" }, { 0x13, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Critical Interrupt", "Bus Timeout" },
{ 0x13, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Critical Interrupt", "I/O Channel check NMI" }, { 0x13, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Critical Interrupt", "I/O Channel check NMI" },
{ 0x13, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Critical Interrupt", "Software NMI" }, { 0x13, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Critical Interrupt", "Software NMI" },
@ -281,10 +373,13 @@ static struct ipmi_event_sensor_types sensor_specific_types[] __attribute__((unu
{ 0x13, 0x07, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Critical Interrupt", "Bus Correctable error" }, { 0x13, 0x07, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Critical Interrupt", "Bus Correctable error" },
{ 0x13, 0x08, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Critical Interrupt", "Bus Uncorrectable error" }, { 0x13, 0x08, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Critical Interrupt", "Bus Uncorrectable error" },
{ 0x13, 0x09, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Critical Interrupt", "Fatal NMI" }, { 0x13, 0x09, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Critical Interrupt", "Fatal NMI" },
{ 0x13, 0x0a, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Critical Interrupt", "Bus Fatal Error" },
{ 0x14, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Button", "Power Button pressed" }, { 0x14, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Button", "Power Button pressed" },
{ 0x14, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Button", "Sleep Button pressed" }, { 0x14, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Button", "Sleep Button pressed" },
{ 0x14, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Button", "Reset Button pressed" }, { 0x14, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Button", "Reset Button pressed" },
{ 0x14, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Button", "FRU Latch" },
{ 0x14, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Button", "FRU Service" },
{ 0x15, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Module/Board", NULL }, { 0x15, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Module/Board", NULL },
{ 0x16, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Microcontroller/Coprocessor", NULL }, { 0x16, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Microcontroller/Coprocessor", NULL },
@ -292,7 +387,10 @@ static struct ipmi_event_sensor_types sensor_specific_types[] __attribute__((unu
{ 0x18, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Chassis", NULL }, { 0x18, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Chassis", NULL },
{ 0x19, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Chip Set", NULL }, { 0x19, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Chip Set", NULL },
{ 0x1a, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Other FRU", NULL }, { 0x1a, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Other FRU", NULL },
{ 0x1b, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Cable/Interconnect", NULL },
{ 0x1b, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Cable/Interconnect", "Connected" },
{ 0x1b, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Cable/Interconnect", "Config Error" },
{ 0x1c, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Terminator", NULL }, { 0x1c, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Terminator", NULL },
{ 0x1d, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Boot Initiated", "Initiated by power up" }, { 0x1d, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Boot Initiated", "Initiated by power up" },
@ -300,6 +398,9 @@ static struct ipmi_event_sensor_types sensor_specific_types[] __attribute__((unu
{ 0x1d, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Boot Initiated", "Initiated by warm reset" }, { 0x1d, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Boot Initiated", "Initiated by warm reset" },
{ 0x1d, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Boot Initiated", "User requested PXE boot" }, { 0x1d, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Boot Initiated", "User requested PXE boot" },
{ 0x1d, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Boot Initiated", "Automatic boot to diagnostic" }, { 0x1d, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Boot Initiated", "Automatic boot to diagnostic" },
{ 0x1d, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Boot Initiated", "OS initiated hard reset" },
{ 0x1d, 0x06, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Boot Initiated", "OS initiated warm reset" },
{ 0x1d, 0x07, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Boot Initiated", "System Restart" },
{ 0x1e, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Boot Error", "No bootable media" }, { 0x1e, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Boot Error", "No bootable media" },
{ 0x1e, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Boot Error", "Non-bootable disk in drive" }, { 0x1e, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Boot Error", "Non-bootable disk in drive" },
@ -315,18 +416,23 @@ static struct ipmi_event_sensor_types sensor_specific_types[] __attribute__((unu
{ 0x1f, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "OS Boot", "ROM boot completed" }, { 0x1f, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "OS Boot", "ROM boot completed" },
{ 0x1f, 0x06, 0xff, IPMI_EVENT_CLASS_DISCRETE, "OS Boot", "boot completed - device not specified" }, { 0x1f, 0x06, 0xff, IPMI_EVENT_CLASS_DISCRETE, "OS Boot", "boot completed - device not specified" },
{ 0x20, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "OS Critical Stop", "Stop during OS load/init" }, { 0x20, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "OS Stop/Shutdown", "Error during system startup" },
{ 0x20, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "OS Critical Stop", "Run-time stop" }, { 0x20, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "OS Stop/Shutdown", "Run-time critical stop" },
{ 0x20, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "OS Stop/Shutdown", "OS graceful stop" },
{ 0x20, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "OS Stop/Shutdown", "OS graceful shutdown" },
{ 0x20, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "OS Stop/Shutdown", "PEF initiated soft shutdown" },
{ 0x20, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "OS Stop/Shutdown", "Agent not responding" },
{ 0x21, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Fault Status asserted" }, { 0x21, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Fault Status" },
{ 0x21, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Identify Status asserted" }, { 0x21, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Identify Status" },
{ 0x21, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Device installed/attached" }, { 0x21, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Device Installed" },
{ 0x21, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Ready for device installation" }, { 0x21, 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, 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, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Slot Power is Off" },
{ 0x21, 0x06, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Device removal request" }, { 0x21, 0x06, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Device Removal Request" },
{ 0x21, 0x07, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Interlock asserted" }, { 0x21, 0x07, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Interlock" },
{ 0x21, 0x08, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Slot is disabled" }, { 0x21, 0x08, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Slot is Disabled" },
{ 0x21, 0x09, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Spare Device" },
{ 0x22, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System ACPI Power State", "S0/G0: working" }, { 0x22, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System ACPI Power State", "S0/G0: working" },
{ 0x22, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System ACPI Power State", "S1: sleeping with system hw & processor context maintained" }, { 0x22, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System ACPI Power State", "S1: sleeping with system hw & processor context maintained" },
@ -371,18 +477,77 @@ static struct ipmi_event_sensor_types sensor_specific_types[] __attribute__((unu
{ 0x28, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Management Subsystem Health", "Controller access degraded or unavailable" }, { 0x28, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Management Subsystem Health", "Controller access degraded or unavailable" },
{ 0x28, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Management Subsystem Health", "Management controller off-line" }, { 0x28, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Management Subsystem Health", "Management controller off-line" },
{ 0x28, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Management Subsystem Health", "Management controller unavailable" }, { 0x28, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Management Subsystem Health", "Management controller unavailable" },
{ 0x28, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Management Subsystem Health", "Sensor failure" },
{ 0x28, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Management Subsystem Health", "FRU failure" },
{ 0x29, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Battery", "Low" }, { 0x29, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Battery", "Low" },
{ 0x29, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Battery", "Failed" }, { 0x29, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Battery", "Failed" },
{ 0x29, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Battery", "Presence Detected" }, { 0x29, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Battery", "Presence Detected" },
{ 0x2b, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Version Change", "Hardware change detected" },
{ 0x2b, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Version Change", "Firmware or software change detected" },
{ 0x2b, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Version Change", "Hardware incompatibility detected" },
{ 0x2b, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Version Change", "Firmware or software incompatibility detected" },
{ 0x2b, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Version Change", "Invalid or unsupported hardware version" },
{ 0x2b, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Version Change", "Invalid or unsupported firmware or software version" },
{ 0x2b, 0x06, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Version Change", "Hardware change success" },
{ 0x2b, 0x07, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Version Change", "Firmware or software change success" },
{ 0x2c, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "FRU State", "Not Installed" },
{ 0x2c, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "FRU State", "Inactive" },
{ 0x2c, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "FRU State", "Activation Requested" },
{ 0x2c, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "FRU State", "Activation in Progress" },
{ 0x2c, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "FRU State", "Active" },
{ 0x2c, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "FRU State", "Deactivation Requested" },
{ 0x2c, 0x06, 0xff, IPMI_EVENT_CLASS_DISCRETE, "FRU State", "Deactivation in Progress" },
{ 0x2c, 0x07, 0xff, IPMI_EVENT_CLASS_DISCRETE, "FRU State", "Communication lost" },
{ 0xF0, 0x00, 0xFF, IPMI_EVENT_CLASS_DISCRETE, "FRU Hot Swap", "Transition to M0" },
{ 0xF0, 0x01, 0xFF, IPMI_EVENT_CLASS_DISCRETE, "FRU Hot Swap", "Transition to M1" },
{ 0xF0, 0x02, 0xFF, IPMI_EVENT_CLASS_DISCRETE, "FRU Hot Swap", "Transition to M2" },
{ 0xF0, 0x03, 0xFF, IPMI_EVENT_CLASS_DISCRETE, "FRU Hot Swap", "Transition to M3" },
{ 0xF0, 0x04, 0xFF, IPMI_EVENT_CLASS_DISCRETE, "FRU Hot Swap", "Transition to M4" },
{ 0xF0, 0x05, 0xFF, IPMI_EVENT_CLASS_DISCRETE, "FRU Hot Swap", "Transition to M5" },
{ 0xF0, 0x06, 0xFF, IPMI_EVENT_CLASS_DISCRETE, "FRU Hot Swap", "Transition to M6" },
{ 0xF0, 0x06, 0xFF, IPMI_EVENT_CLASS_DISCRETE, "FRU Hot Swap", "Transition to M7" },
{ 0xF1, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "IPMB-0 Status", "IPMB-A disabled, IPMB-B disabled" },
{ 0xF1, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "IPMB-0 Status", "IPMB-A enabled, IPMB-B disabled" },
{ 0xF1, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "IPMB-0 Status", "IPMB-A disabled, IPMB-B enabled" },
{ 0xF1, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "IPMB-0 Status", "IPMB-A enabled, IPMP-B enabled" },
{ 0xF2, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Module Hot Swap", "Module Handle Closed" },
{ 0xF2, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Module Hot Swap", "Module Handle Opened" },
{ 0xF2, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Module Hot Swap", "Quiesced" },
{ 0xC0, 0x00, 0xff, 0x00, "OEM", NULL },
{ 0x00, 0x00, 0x00, 0x00, NULL, NULL }, { 0x00, 0x00, 0x00, 0x00, NULL, NULL },
}; };
/* These values are IANA numbers */
typedef enum IPMI_OEM {
IPMI_OEM_UNKNOWN = 0,
IPMI_OEM_SUN = 42,
IPMI_OEM_INTEL = 343,
IPMI_OEM_TYAN = 6653,
IPMI_OEM_NEWISYS = 9237,
IPMI_OEM_SUPERMICRO = 10876,
IPMI_OEM_KONTRON = 15000,
} IPMI_OEM;
int ipmi_sel_main(struct ipmi_intf *, int, char **); 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(struct ipmi_intf * intf, struct sel_event_record * evt);
void ipmi_sel_print_std_entry_verbose(struct sel_event_record * evt); void ipmi_sel_print_std_entry_verbose(struct ipmi_intf * intf, struct sel_event_record * evt);
void ipmi_get_event_desc(struct sel_event_record * rec, char ** desc); void ipmi_sel_print_extended_entry(struct ipmi_intf * intf, struct sel_event_record * evt);
void ipmi_sel_print_extended_entry_verbose(struct ipmi_intf * intf, struct sel_event_record * evt);
void ipmi_get_event_desc(struct ipmi_intf * intf, struct sel_event_record * rec, char ** desc);
const char * ipmi_sel_get_sensor_type(uint8_t code); const char * ipmi_sel_get_sensor_type(uint8_t code);
const char * ipmi_sel_get_sensor_type_offset(uint8_t code, uint8_t offset);
uint16_t ipmi_sel_get_std_entry(struct ipmi_intf * intf, uint16_t id, struct sel_event_record * evt);
char * get_newisys_evt_desc(struct ipmi_intf * intf, struct sel_event_record * rec);
IPMI_OEM ipmi_get_oem(struct ipmi_intf * intf);
char * ipmi_get_oem_desc(struct ipmi_intf * intf, struct sel_event_record * rec);
#endif /* IPMI_SEL_H */ #endif /* IPMI_SEL_H */

View File

@ -42,13 +42,6 @@
#include <ipmitool/ipmi.h> #include <ipmitool/ipmi.h>
#include <ipmitool/ipmi_sdr.h> #include <ipmitool/ipmi_sdr.h>
/* ipmi sensor commands */
#define GET_SENSOR_READING 0x2d
#define GET_SENSOR_FACTORS 0x23
#define SET_SENSOR_THRESHOLDS 0x26
#define GET_SENSOR_THRESHOLDS 0x27
#define GET_SENSOR_TYPE 0x2f
/* threshold specification bits for analog sensors for get sensor threshold command /* threshold specification bits for analog sensors for get sensor threshold command
* and set sensor threshold command * and set sensor threshold command
*/ */

View File

@ -39,6 +39,7 @@
#include <ipmitool/ipmi.h> #include <ipmitool/ipmi.h>
#define SOL_ESCAPE_CHARACTER_DEFAULT '~'
#define IPMI_SOL_SERIAL_ALERT_MASK_SUCCEED 0x08 #define IPMI_SOL_SERIAL_ALERT_MASK_SUCCEED 0x08
#define IPMI_SOL_SERIAL_ALERT_MASK_DEFERRED 0x04 #define IPMI_SOL_SERIAL_ALERT_MASK_DEFERRED 0x04

View File

@ -42,7 +42,7 @@
extern const struct valstr completion_code_vals[]; extern const struct valstr completion_code_vals[];
extern const struct valstr entity_id_vals[]; extern const struct valstr entity_id_vals[];
extern const struct valstr entity_device_type_vals[]; extern const struct valstr entity_device_type_vals[];
extern const struct valstr ipmi_netfn_vals[];
extern const struct valstr ipmi_channel_activity_type_vals[]; extern const struct valstr ipmi_channel_activity_type_vals[];
extern const struct valstr ipmi_privlvl_vals[]; extern const struct valstr ipmi_privlvl_vals[];
extern const struct valstr impi_bit_rate_vals[]; extern const struct valstr impi_bit_rate_vals[];
@ -51,5 +51,11 @@ extern const struct valstr ipmi_authtype_session_vals[];
extern const struct valstr ipmi_authtype_vals[]; extern const struct valstr ipmi_authtype_vals[];
extern const struct valstr ipmi_channel_protocol_vals[]; extern const struct valstr ipmi_channel_protocol_vals[];
extern const struct valstr ipmi_channel_medium_vals[]; extern const struct valstr ipmi_channel_medium_vals[];
extern const struct valstr ipmi_chassis_power_control_vals[];
extern const struct valstr ipmi_auth_algorithms[];
extern const struct valstr ipmi_integrity_algorithms[];
extern const struct valstr ipmi_encryption_algorithms[];
extern const struct valstr ipmi_oem_info[];
#endif /*IPMI_STRINGS_H*/ #endif /*IPMI_STRINGS_H*/

View File

@ -0,0 +1,61 @@
/*
* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistribution of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistribution in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind.
* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
* SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE
* FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
* SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
* OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
* PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
* LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed or intended for use
* in the design, construction, operation or maintenance of any nuclear
* facility.
*/
#ifndef IPMI_SUNOEM_H
#define IPMI_SUNOEM_H
#if HAVE_CONFIG_H
# include <config.h>
#endif
#include <ipmitool/ipmi.h>
#include <ipmitool/ipmi_sdr.h>
#define IPMI_NETFN_SUNOEM 0x2e
#define IPMI_SUNOEM_SET_SSH_KEY 0x01
#define IPMI_SUNOEM_DEL_SSH_KEY 0x02
#define IPMI_SUNOEM_GET_HEALTH_STATUS 0x10
#define IPMI_SUNOEM_SET_FAN_SPEED 0x20
#define IPMI_SUNOEM_LED_GET 0x21
#define IPMI_SUNOEM_LED_SET 0x22
int ipmi_sunoem_main(struct ipmi_intf *, int, char **);
struct ipmi_rs * sunoem_led_get(struct ipmi_intf * intf, struct sdr_record_generic_locator * dev, int ledtype);
struct ipmi_rs * sunoem_led_set(struct ipmi_intf * intf, struct sdr_record_generic_locator * dev, int ledtype, int ledmode);
#endif /*IPMI_SUNOEM_H*/

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) 2005 Tyan Computer Corp. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistribution of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistribution in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind.
* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
* SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE
* FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
* SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
* OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
* PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
* LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed or intended for use
* in the design, construction, operation or maintenance of any nuclear
* facility.
*/
#ifndef IPMI_TSOL_H
#define IPMI_TSOL_H
#include <ipmitool/ipmi.h>
#define IPMI_TSOL_CMD_SENDKEY 0x03
#define IPMI_TSOL_CMD_START 0x06
#define IPMI_TSOL_CMD_STOP 0x02
#define IPMI_TSOL_DEF_PORT 6230
int ipmi_tsol_main(struct ipmi_intf *, int, char **);
#endif /* IPMI_TSOL_H */

View File

@ -40,7 +40,9 @@ libipmitool_la_SOURCES = helper.c ipmi_sdr.c ipmi_sel.c ipmi_sol.c ipmi_pef.c \
ipmi_lanp.c ipmi_fru.c ipmi_chassis.c ipmi_mc.c log.c \ ipmi_lanp.c ipmi_fru.c ipmi_chassis.c ipmi_mc.c log.c \
dimm_spd.c ipmi_sensor.c ipmi_channel.c ipmi_event.c \ dimm_spd.c ipmi_sensor.c ipmi_channel.c ipmi_event.c \
ipmi_session.c ipmi_strings.c ipmi_user.c ipmi_raw.c \ ipmi_session.c ipmi_strings.c ipmi_user.c ipmi_raw.c \
ipmi_oem.c ipmi_oem.c ipmi_isol.c ipmi_sunoem.c ipmi_fwum.c ipmi_picmg.c \
ipmi_main.c ipmi_tsol.c
libipmitool_la_LDFLAGS = -export-dynamic libipmitool_la_LDFLAGS = -export-dynamic
libipmitool_la_LIBADD = -lm libipmitool_la_LIBADD = -lm
libipmitool_la_DEPENDENCIES = libipmitool_la_DEPENDENCIES =

View File

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

View File

@ -34,17 +34,28 @@
* facility. * facility.
*/ */
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h> /* For TIOCNOTTY */
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <inttypes.h> #include <inttypes.h>
#include <signal.h> #include <signal.h>
#include <string.h> #include <string.h>
#include <sys/types.h> #include <strings.h>
#include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
#include <errno.h> #include <errno.h>
#if HAVE_CONFIG_H
# include <config.h>
#endif
#ifdef HAVE_PATHS_H
# include <paths.h> /* For _PATH_TTY */
#endif
#include <ipmitool/helper.h> #include <ipmitool/helper.h>
#include <ipmitool/log.h> #include <ipmitool/log.h>
@ -100,12 +111,11 @@ void printbuf(const uint8_t * buf, int len, const char * desc)
const char * val2str(uint16_t val, const struct valstr *vs) const char * val2str(uint16_t val, const struct valstr *vs)
{ {
static char un_str[16]; static char un_str[16];
int i = 0; int i;
while (vs[i].str != NULL) { for (i = 0; vs[i].str != NULL; i++) {
if (vs[i].val == val) if (vs[i].val == val)
return vs[i].str; return vs[i].str;
i++;
} }
memset(un_str, 0, 16); memset(un_str, 0, 16);
@ -116,15 +126,111 @@ const char * val2str(uint16_t val, const struct valstr *vs)
uint16_t str2val(const char *str, const struct valstr *vs) uint16_t str2val(const char *str, const struct valstr *vs)
{ {
int i = 0; int i;
while (vs[i].str != NULL) { for (i = 0; vs[i].str != NULL; i++) {
if (!strncasecmp(vs[i].str, str, strlen(str))) if (strncasecmp(vs[i].str, str, __maxlen(str, vs[i].str)) == 0)
return vs[i].val; return vs[i].val;
i++;
} }
return 0; return vs[i].val;
}
/* print_valstr - print value string list to log or stdout
*
* @vs: value string list to print
* @title: name of this value string list
* @loglevel: what log level to print, -1 for stdout
*/
void
print_valstr(const struct valstr * vs, const char * title, int loglevel)
{
int i;
if (vs == NULL)
return;
if (title != NULL) {
if (loglevel < 0)
printf("\n%s:\n\n");
else
lprintf(loglevel, "\n%s:\n", title);
}
if (loglevel < 0) {
printf(" VALUE\tHEX\tSTRING\n");
printf("==============================================\n");
} else {
lprintf(loglevel, " VAL\tHEX\tSTRING");
lprintf(loglevel, "==============================================");
}
for (i = 0; vs[i].str != NULL; i++) {
if (loglevel < 0) {
if (vs[i].val < 256)
printf(" %d\t0x%02x\t%s\n", vs[i].val, vs[i].val, vs[i].str);
else
printf(" %d\t0x%04x\t%s\n", vs[i].val, vs[i].val, vs[i].str);
} else {
if (vs[i].val < 256)
lprintf(loglevel, " %d\t0x%02x\t%s", vs[i].val, vs[i].val, vs[i].str);
else
lprintf(loglevel, " %d\t0x%04x\t%s", vs[i].val, vs[i].val, vs[i].str);
}
}
if (loglevel < 0)
printf("\n");
else
lprintf(loglevel, "");
}
/* print_valstr_2col - print value string list in two columns to log or stdout
*
* @vs: value string list to print
* @title: name of this value string list
* @loglevel: what log level to print, -1 for stdout
*/
void
print_valstr_2col(const struct valstr * vs, const char * title, int loglevel)
{
int i;
if (vs == NULL)
return;
if (title != NULL) {
if (loglevel < 0)
printf("\n%s:\n\n");
else
lprintf(loglevel, "\n%s:\n", title);
}
for (i = 0; vs[i].str != NULL; i++) {
if (vs[i+1].str == NULL) {
/* last one */
if (loglevel < 0) {
printf(" %4d %-32s\n", vs[i].val, vs[i].str);
} else {
lprintf(loglevel, " %4d %-32s\n", vs[i].val, vs[i].str);
}
}
else {
if (loglevel < 0) {
printf(" %4d %-32s %4d %-32s\n",
vs[i].val, vs[i].str, vs[i+1].val, vs[i+1].str);
} else {
lprintf(loglevel, " %4d %-32s %4d %-32s\n",
vs[i].val, vs[i].str, vs[i+1].val, vs[i+1].str);
}
i++;
}
}
if (loglevel < 0)
printf("\n");
else
lprintf(loglevel, "");
} }
/* ipmi_csum - calculate an ipmi checksum /* ipmi_csum - calculate an ipmi checksum
@ -227,3 +333,66 @@ ipmi_open_file(const char * file, int rw)
return fp; return fp;
} }
void
ipmi_start_daemon(void)
{
pid_t pid;
int fd;
#ifdef SIGHUP
sigset_t sighup;
#endif
/* if we are started from init no need to become daemon */
if (getppid() == 1)
return;
#ifdef SIGHUP
sigemptyset(&sighup);
sigaddset(&sighup, SIGHUP);
if (sigprocmask(SIG_UNBLOCK, &sighup, NULL) < 0)
fprintf(stderr, "ERROR: could not unblock SIGHUP signal\n");
signal(SIGHUP, SIG_IGN);
#endif
#ifdef SIGTTOU
signal(SIGTTOU, SIG_IGN);
#endif
#ifdef SIGTTIN
signal(SIGTTIN, SIG_IGN);
#endif
#ifdef SIGQUIT
signal(SIGQUIT, SIG_IGN);
#endif
#ifdef SIGTSTP
signal(SIGTSTP, SIG_IGN);
#endif
pid = (pid_t) fork();
if (pid < 0 || pid > 0)
exit(0);
#if defined(SIGTSTP) && defined(TIOCNOTTY)
if (setpgid(0, getpid()) == -1)
exit(1);
if ((fd = open(_PATH_TTY, O_RDWR)) >= 0) {
ioctl(fd, TIOCNOTTY, NULL);
close(fd);
}
#else
if (setpgrp() == -1)
exit(1);
pid = (pid_t) fork();
if (pid < 0 || pid > 0)
exit(0);
#endif
chdir("/");
umask(0);
for (fd=0; fd<64; fd++)
close(fd);
open("/dev/null", O_RDWR);
dup(0);
dup(0);
}

View File

@ -1,4 +1,4 @@
/* /* -*-mode: C; indent-tabs-mode: t; -*-
* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -37,6 +37,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <strings.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
@ -54,6 +55,9 @@
#include <ipmitool/ipmi_strings.h> #include <ipmitool/ipmi_strings.h>
#include <ipmitool/ipmi_constants.h> #include <ipmitool/ipmi_constants.h>
extern int csv_output;
extern int verbose;
void printf_channel_usage (void); void printf_channel_usage (void);
/** /**
@ -189,6 +193,7 @@ ipmi_get_channel_info(struct ipmi_intf * intf, uint8_t channel)
struct ipmi_rs * rsp; struct ipmi_rs * rsp;
struct ipmi_rq req; struct ipmi_rq req;
uint8_t rqdata[2]; uint8_t rqdata[2];
uint8_t medium;
struct get_channel_info_rsp channel_info; struct get_channel_info_rsp channel_info;
struct get_channel_access_rsp channel_access; struct get_channel_access_rsp channel_access;
@ -245,6 +250,12 @@ ipmi_get_channel_info(struct ipmi_intf * intf, uint8_t channel)
channel_info.vendor_id[2] << 16); channel_info.vendor_id[2] << 16);
/* only proceed if this is LAN channel */
medium = ipmi_get_channel_medium(intf, channel);
if (medium != IPMI_CHANNEL_MEDIUM_LAN &&
medium != IPMI_CHANNEL_MEDIUM_LAN_OTHER) {
return 0;
}
memset(&req, 0, sizeof(req)); memset(&req, 0, sizeof(req));
rqdata[0] = channel & 0xf; rqdata[0] = channel & 0xf;
@ -353,8 +364,6 @@ ipmi_get_user_access(struct ipmi_intf * intf, uint8_t channel, uint8_t userid)
struct get_user_access_rsp user_access; struct get_user_access_rsp user_access;
int curr_uid, max_uid = 0, init = 1; int curr_uid, max_uid = 0, init = 1;
ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN);
curr_uid = userid ? : 1; curr_uid = userid ? : 1;
memset(&req1, 0, sizeof(req1)); memset(&req1, 0, sizeof(req1));
@ -441,8 +450,6 @@ ipmi_set_user_access(struct ipmi_intf * intf, int argc, char ** argv)
struct set_user_access_data set_access; struct set_user_access_data set_access;
int i; int i;
ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN);
if ((argc < 3) || (strncmp(argv[0], "help", 4) == 0)) { if ((argc < 3) || (strncmp(argv[0], "help", 4) == 0)) {
printf_channel_usage(); printf_channel_usage();
return 0; return 0;
@ -475,6 +482,7 @@ ipmi_set_user_access(struct ipmi_intf * intf, int argc, char ** argv)
memcpy(&user_access, rsp->data, sizeof(struct get_user_access_rsp)); memcpy(&user_access, rsp->data, sizeof(struct get_user_access_rsp));
memset(&set_access, 0, sizeof(set_access));
set_access.change_bits = 1; set_access.change_bits = 1;
set_access.callin_callback = user_access.callin_callback; set_access.callin_callback = user_access.callin_callback;
set_access.link_auth = user_access.link_auth; set_access.link_auth = user_access.link_auth;
@ -526,6 +534,204 @@ ipmi_set_user_access(struct ipmi_intf * intf, int argc, char ** argv)
return 0; return 0;
} }
static const char *
iana_string(uint32_t iana)
{
static char s[10];
if (iana)
{
sprintf(s, "%06x", iana);
return s;
}
else
return "N/A";
}
static int
ipmi_get_channel_cipher_suites(struct ipmi_intf * intf,
const char * payload_type,
uint8_t channel)
{
struct ipmi_rs * rsp;
struct ipmi_rq req;
uint8_t oem_record;
uint8_t rqdata[3];
uint32_t iana;
uint8_t auth_alg, integrity_alg, crypt_alg;
uint8_t cipher_suite_id;
uint8_t list_index = 0;
uint8_t cipher_suite_data[1024]; // 0x40 sets * 16 bytes per set
uint16_t offset = 0;
uint16_t cipher_suite_data_length = 0; // how much was returned, total
memset(cipher_suite_data, 0, sizeof(cipher_suite_data));
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_APP; // 0x06
req.msg.cmd = IPMI_GET_CHANNEL_CIPHER_SUITES; // 0x54
req.msg.data = rqdata;
req.msg.data_len = 3;
rqdata[0] = channel;
rqdata[1] = ((strncmp(payload_type, "ipmi", 4) == 0)? 0: 1);
rqdata[2] = 0x80; // Always ask for cipher suite format
rsp = intf->sendrecv(intf, &req);
if (rsp == NULL) {
lprintf(LOG_ERR, "Unable to Get Channel Cipher Suites");
return -1;
}
if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Get Channel Cipher Suites failed: %s",
val2str(rsp->ccode, completion_code_vals));
return -1;
}
// Grab the returned channel number once. We assume it's the same
// in future calls.
if (rsp->data_len >= 1)
channel = rsp->data[0];
while ((rsp->data_len > 1) && (list_index < 0x3F))
{
//
// We got back cipher suite data -- store it.
//
//printf("copying data to offset %d\n", offset);
//printbuf(rsp->data + 1, rsp->data_len - 1, "this is the data");
memcpy(cipher_suite_data + offset, rsp->data + 1, rsp->data_len - 1);
offset += rsp->data_len - 1;
//
// Increment our list for the next call
//
++list_index;
rqdata[2] = (rqdata[2] & 0x80) + list_index;
rsp = intf->sendrecv(intf, &req);
if (rsp == NULL) {
lprintf(LOG_ERR, "Unable to Get Channel Cipher Suites");
return -1;
}
if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Get Channel Cipher Suites failed: %s",
val2str(rsp->ccode, completion_code_vals));
return -1;
}
}
//
// We can chomp on all our data now.
//
cipher_suite_data_length = offset;
offset = 0;
if (! csv_output)
printf("ID IANA Auth Alg Integrity Alg Confidentiality Alg\n");
while (offset < cipher_suite_data_length)
{
if (cipher_suite_data[offset++] == 0xC0)
{
oem_record = 0; // standard type
iana = 0;
// Verify that we have at least a full record left
if ((cipher_suite_data_length - offset) < 4) // id + 3 algs
{
lprintf(LOG_ERR, "Incomplete data record in cipher suite data");
return -1;
}
cipher_suite_id = cipher_suite_data[offset++];
}
else if (cipher_suite_data[offset++] == 0xC1)
{
oem_record = 1; // OEM record type
// Verify that we have at least a full record left
if ((cipher_suite_data_length - offset) < 4) // id + iana + 3 algs
{
lprintf(LOG_ERR, "Incomplete data record in cipher suite data");
return -1;
}
cipher_suite_id = cipher_suite_data[offset++];
//
// Grab the IANA
//
iana =
cipher_suite_data[offset] |
(cipher_suite_data[offset + 1] << 8) |
(cipher_suite_data[offset + 2] << 16);
offset += 3;
}
else
{
lprintf(LOG_ERR, "Bad start of record byte in cipher suite data");
return -1;
}
//
// Grab the algorithms for this cipher suite. I guess we can't be
// sure of what order they'll come in. Also, I suppose we default
// to the NONE algorithm if one were absent. This part of the spec is
// poorly written -- I have read the errata document. For now, I'm only
// allowing one algorithm per type (auth, integrity, crypt) because I
// don't I understand how it could be otherwise.
//
auth_alg = IPMI_AUTH_RAKP_NONE;
integrity_alg = IPMI_INTEGRITY_NONE;
crypt_alg = IPMI_CRYPT_NONE;
while (((cipher_suite_data[offset] & 0xC0) != 0xC0) &&
((cipher_suite_data_length - offset) > 0))
{
switch (cipher_suite_data[offset] & 0xC0)
{
case 0x00:
// Authentication algorithm specifier
auth_alg = cipher_suite_data[offset++] & 0x3F;
break;
case 0x40:
// Interity algorithm specifier
integrity_alg = cipher_suite_data[offset++] & 0x3F;
break;
case 0x80:
// Confidentiality algorithm specifier
crypt_alg = cipher_suite_data[offset++] & 0x3F;
break;
}
}
//
// We have everything we need to spit out a cipher suite record
//
printf((csv_output? "%d,%s,%s,%s,%s\n" :
"%-4d %-7s %-15s %-15s %-15s\n"),
cipher_suite_id,
iana_string(iana),
val2str(auth_alg, ipmi_auth_algorithms),
val2str(integrity_alg, ipmi_integrity_algorithms),
val2str(crypt_alg, ipmi_encryption_algorithms));
}
return 0;
}
uint8_t uint8_t
ipmi_get_channel_medium(struct ipmi_intf * intf, uint8_t channel) ipmi_get_channel_medium(struct ipmi_intf * intf, uint8_t channel)
{ {
@ -545,9 +751,11 @@ ipmi_get_channel_medium(struct ipmi_intf * intf, uint8_t channel)
return -1; return -1;
} }
if (rsp->ccode > 0) { if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Get Channel Info command failed: %s", if (rsp->ccode == 0xcc)
return IPMI_CHANNEL_MEDIUM_RESERVED;
lprintf(LOG_INFO, "Get Channel Info command failed: %s",
val2str(rsp->ccode, completion_code_vals)); val2str(rsp->ccode, completion_code_vals));
return -1; return IPMI_CHANNEL_MEDIUM_RESERVED;
} }
memcpy(&info, rsp->data, sizeof(struct get_channel_info_rsp)); memcpy(&info, rsp->data, sizeof(struct get_channel_info_rsp));
@ -571,7 +779,8 @@ printf_channel_usage()
lprintf(LOG_NOTICE, " getaccess <channel number> [user id]"); lprintf(LOG_NOTICE, " getaccess <channel number> [user id]");
lprintf(LOG_NOTICE, " setaccess <channel number> " lprintf(LOG_NOTICE, " setaccess <channel number> "
"<user id> [callin=on|off] [ipmi=on|off] [link=on|off] [privilege=level]"); "<user id> [callin=on|off] [ipmi=on|off] [link=on|off] [privilege=level]");
lprintf(LOG_NOTICE, " info [channel number]\n"); lprintf(LOG_NOTICE, " info [channel number]");
lprintf(LOG_NOTICE, " getciphers <ipmi | sol> [channel]\n");
lprintf(LOG_NOTICE, "Possible privilege levels are:"); lprintf(LOG_NOTICE, "Possible privilege levels are:");
lprintf(LOG_NOTICE, " 1 Callback level"); lprintf(LOG_NOTICE, " 1 Callback level");
lprintf(LOG_NOTICE, " 2 User level"); lprintf(LOG_NOTICE, " 2 User level");
@ -627,6 +836,23 @@ ipmi_channel_main(struct ipmi_intf * intf, int argc, char ** argv)
retval = ipmi_get_channel_info(intf, ch); retval = ipmi_get_channel_info(intf, ch);
} }
} }
// it channel getciphers <ipmi | sol> [channel]
else if (strncmp(argv[0], "getciphers", 10) == 0)
{
if ((argc < 2) || (argc > 3) ||
(strncmp(argv[1], "ipmi", 4) && strncmp(argv[1], "sol", 3)))
printf_channel_usage();
else
{
uint8_t ch = 0xe;
if (argc == 4)
ch = (uint8_t)strtol(argv[2], NULL, 0);
retval = ipmi_get_channel_cipher_suites(intf,
argv[1], // ipmi | sol
ch);
}
}
else else
{ {
printf("Invalid CHANNEL command: %s\n", argv[0]); printf("Invalid CHANNEL command: %s\n", argv[0]);

View File

@ -42,11 +42,12 @@
#include <ipmitool/ipmi.h> #include <ipmitool/ipmi.h>
#include <ipmitool/log.h> #include <ipmitool/log.h>
#include <ipmitool/ipmi_intf.h> #include <ipmitool/ipmi_intf.h>
#include <ipmitool/ipmi_strings.h>
#include <ipmitool/ipmi_chassis.h> #include <ipmitool/ipmi_chassis.h>
extern int verbose; extern int verbose;
static int int
ipmi_chassis_power_status(struct ipmi_intf * intf) ipmi_chassis_power_status(struct ipmi_intf * intf)
{ {
struct ipmi_rs * rsp; struct ipmi_rs * rsp;
@ -68,29 +69,28 @@ ipmi_chassis_power_status(struct ipmi_intf * intf)
return -1; return -1;
} }
printf("Chassis Power is %s\n", (rsp->data[0] & 0x1) ? "on" : "off"); return rsp->data[0] & 1;
}
static int
ipmi_chassis_print_power_status(struct ipmi_intf * intf)
{
int ps = ipmi_chassis_power_status(intf);
if (ps < 0)
return -1;
printf("Chassis Power is %s\n", ps ? "on" : "off");
return 0; return 0;
} }
static const struct valstr ipmi_chassis_power_control_vals[] = { int
{ 0x00, "Down/Off" },
{ 0x01, "Up/On" },
{ 0x02, "Cycle" },
{ 0x03, "Reset" },
{ 0x04, "Pulse" },
{ 0x05, "Soft" },
{ 0x00, NULL },
};
static int
ipmi_chassis_power_control(struct ipmi_intf * intf, uint8_t ctl) ipmi_chassis_power_control(struct ipmi_intf * intf, uint8_t ctl)
{ {
struct ipmi_rs * rsp; struct ipmi_rs * rsp;
struct ipmi_rq req; struct ipmi_rq req;
ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN);
memset(&req, 0, sizeof(req)); memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_CHASSIS; req.msg.netfn = IPMI_NETFN_CHASSIS;
req.msg.cmd = 0x2; req.msg.cmd = 0x2;
@ -113,8 +113,10 @@ ipmi_chassis_power_control(struct ipmi_intf * intf, uint8_t ctl)
printf("Chassis Power Control: %s\n", printf("Chassis Power Control: %s\n",
val2str(ctl, ipmi_chassis_power_control_vals)); val2str(ctl, ipmi_chassis_power_control_vals));
#if 0 /* this can cause sessions to hang around after power commands */
/* sessions often get lost when changing chassis power */ /* sessions often get lost when changing chassis power */
intf->abort = 1; intf->abort = 1;
#endif
return 0; return 0;
} }
@ -130,8 +132,6 @@ ipmi_chassis_identify(struct ipmi_intf * intf, char * arg)
uint8_t force_on; uint8_t force_on;
} identify_data; } identify_data;
ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN);
memset(&req, 0, sizeof(req)); memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_CHASSIS; req.msg.netfn = IPMI_NETFN_CHASSIS;
req.msg.cmd = 0x4; req.msg.cmd = 0x4;
@ -213,6 +213,8 @@ ipmi_chassis_poh(struct ipmi_intf * intf)
printf("POH Counter : %li hours total (%li days, %li hours)\n", printf("POH Counter : %li hours total (%li days, %li hours)\n",
(long)count, (long)(count / 24), (long)(count % 24)); (long)count, (long)(count / 24), (long)(count % 24));
return 0;
} }
static int static int
@ -358,6 +360,75 @@ ipmi_chassis_status(struct ipmi_intf * intf)
return 0; return 0;
} }
static int
ipmi_chassis_selftest(struct ipmi_intf * intf)
{
struct ipmi_rs * rsp;
struct ipmi_rq req;
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_APP;
req.msg.cmd = 0x4;
rsp = intf->sendrecv(intf, &req);
if (rsp == NULL) {
lprintf(LOG_ERR, "Error sending Get Self Test command");
return -1;
}
if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Error sending Get Self Test command: %s",
val2str(rsp->ccode, completion_code_vals));
return -1;
}
printf("Self Test Results : ");
switch (rsp->data[0]) {
case 0x55:
printf("passed\n");
break;
case 0x56:
printf("not implemented\n");
break;
case 0x57:
{
int i;
const struct valstr broken_dev_vals[] = {
{ 0, "firmware corrupted" },
{ 1, "boot block corrupted" },
{ 2, "FRU Internal Use Area corrupted" },
{ 3, "SDR Repository empty" },
{ 4, "IPMB not responding" },
{ 5, "cannot access BMC FRU" },
{ 6, "cannot access SDR Repository" },
{ 7, "cannot access SEL Device" },
{ 0xff, NULL },
};
printf("device error\n");
for (i=0; i<8; i++) {
if (rsp->data[1] & (1<<i)) {
printf(" [%s]\n",
val2str(i, broken_dev_vals));
}
}
}
break;
case 0x58:
printf("Fatal hardware error: %02xh\n", rsp->data[1]);
break;
default:
printf("Device-specific failure %02xh:%02xh\n",
rsp->data[0], rsp->data[1]);
break;
}
return 0;
}
static int static int
ipmi_chassis_set_bootparam(struct ipmi_intf * intf, uint8_t param, uint8_t * data, int len) ipmi_chassis_set_bootparam(struct ipmi_intf * intf, uint8_t param, uint8_t * data, int len)
{ {
@ -365,8 +436,6 @@ ipmi_chassis_set_bootparam(struct ipmi_intf * intf, uint8_t param, uint8_t * dat
struct ipmi_rq req; struct ipmi_rq req;
uint8_t msg_data[16]; uint8_t msg_data[16];
ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN);
memset(msg_data, 0, 16); memset(msg_data, 0, 16);
msg_data[0] = param & 0x7f; msg_data[0] = param & 0x7f;
memcpy(msg_data+1, data, len); memcpy(msg_data+1, data, len);
@ -388,7 +457,7 @@ ipmi_chassis_set_bootparam(struct ipmi_intf * intf, uint8_t param, uint8_t * dat
return -1; return -1;
} }
printf("Chassis Set Boot Parameter %d to %s\n", param, data); lprintf(LOG_DEBUG, "Chassis Set Boot Parameter %d to %s", param, buf2str(data, len));
return 0; return 0;
} }
@ -435,41 +504,57 @@ ipmi_chassis_get_bootparam(struct ipmi_intf * intf, char * arg)
} }
static int static int
ipmi_chassis_set_bootflag(struct ipmi_intf * intf, char * arg) ipmi_chassis_set_bootdev(struct ipmi_intf * intf, char * arg, int clearcmos)
{ {
uint8_t flags[5]; uint8_t flags[5];
int rc = 0; int rc = 0;
ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN); memset(flags, 0, 5);
flags[0] = 0x01;
if (arg == NULL) { flags[1] = 0x01;
lprintf(LOG_ERR, "No bootflag argument supplied"); rc = ipmi_chassis_set_bootparam(intf, 4, flags, 2);
if (rc < 0)
return -1; return -1;
}
if (strncmp(arg, "force_pxe", 9) == 0) memset(flags, 0, 5);
if (arg == NULL)
flags[1] = 0x00;
else if (strncmp(arg, "none", 4) == 0)
flags[1] = 0x00;
else if (strncmp(arg, "pxe", 3) == 0 ||
strncmp(arg, "force_pxe", 9) == 0)
flags[1] = 0x04; flags[1] = 0x04;
else if (strncmp(arg, "force_disk", 10) == 0) else if (strncmp(arg, "disk", 4) == 0 ||
strncmp(arg, "force_disk", 10) == 0)
flags[1] = 0x08; flags[1] = 0x08;
else if (strncmp(arg, "force_diag", 10) == 0) else if (strncmp(arg, "safe", 4) == 0 ||
strncmp(arg, "force_safe", 10) == 0)
flags[1] = 0x0c;
else if (strncmp(arg, "diag", 4) == 0 ||
strncmp(arg, "force_diag", 10) == 0)
flags[1] = 0x10; flags[1] = 0x10;
else if (strncmp(arg, "force_cdrom", 11) == 0) else if (strncmp(arg, "cdrom", 5) == 0 ||
strncmp(arg, "force_cdrom", 11) == 0)
flags[1] = 0x14; flags[1] = 0x14;
else if (strncmp(arg, "force_floppy", 12) == 0) else if (strncmp(arg, "floppy", 6) == 0 ||
strncmp(arg, "force_floppy", 12) == 0)
flags[1] = 0x3c; flags[1] = 0x3c;
else if (strncmp(arg, "bios", 4) == 0 ||
strncmp(arg, "force_bios", 10) == 0)
flags[1] = 0x18;
else { else {
lprintf(LOG_ERR, "Invalid bootflag: %s", arg); lprintf(LOG_ERR, "Invalid argument: %s", arg);
return -1; return -1;
} }
flags[0] = 0x80; /* set flag valid bit */ if (clearcmos)
flags[1] |= 0x80;
/* set flag valid bit */
flags[0] = 0x80;
rc = ipmi_chassis_set_bootparam(intf, 5, flags, 5); rc = ipmi_chassis_set_bootparam(intf, 5, flags, 5);
if (rc == 0)
if (rc < 0) { printf("Set Boot Device to %s\n", arg);
flags[0] = 0x08; /* don't automatically clear boot flag valid bit in 60 seconds */
rc = ipmi_chassis_set_bootparam(intf, 3, flags, 1);
}
return rc; return rc;
} }
@ -479,8 +564,6 @@ ipmi_chassis_power_policy(struct ipmi_intf * intf, uint8_t policy)
struct ipmi_rs * rsp; struct ipmi_rs * rsp;
struct ipmi_rq req; struct ipmi_rq req;
ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN);
memset(&req, 0, sizeof(req)); memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_CHASSIS; req.msg.netfn = IPMI_NETFN_CHASSIS;
req.msg.cmd = 0x6; req.msg.cmd = 0x6;
@ -527,17 +610,55 @@ ipmi_chassis_power_policy(struct ipmi_intf * intf, uint8_t policy)
return 0; return 0;
} }
int
ipmi_power_main(struct ipmi_intf * intf, int argc, char ** argv)
{
int rc = 0;
uint8_t ctl = 0;
if ((argc < 1) || (strncmp(argv[0], "help", 4) == 0)) {
lprintf(LOG_NOTICE, "chassis power Commands: status, on, off, cycle, reset, diag, soft");
return 0;
}
if (strncmp(argv[0], "status", 6) == 0) {
rc = ipmi_chassis_print_power_status(intf);
return rc;
}
if ((strncmp(argv[0], "up", 2) == 0) || (strncmp(argv[0], "on", 2) == 0))
ctl = IPMI_CHASSIS_CTL_POWER_UP;
else if ((strncmp(argv[0], "down", 4) == 0) || (strncmp(argv[0], "off", 3) == 0))
ctl = IPMI_CHASSIS_CTL_POWER_DOWN;
else if (strncmp(argv[0], "cycle", 5) == 0)
ctl = IPMI_CHASSIS_CTL_POWER_CYCLE;
else if (strncmp(argv[0], "reset", 5) == 0)
ctl = IPMI_CHASSIS_CTL_HARD_RESET;
else if (strncmp(argv[0], "diag", 4) == 0)
ctl = IPMI_CHASSIS_CTL_PULSE_DIAG;
else if ((strncmp(argv[0], "acpi", 4) == 0) || (strncmp(argv[0], "soft", 4) == 0))
ctl = IPMI_CHASSIS_CTL_ACPI_SOFT;
else {
lprintf(LOG_ERR, "Invalid chassis power command: %s", argv[0]);
return -1;
}
rc = ipmi_chassis_power_control(intf, ctl);
return rc;
}
int int
ipmi_chassis_main(struct ipmi_intf * intf, int argc, char ** argv) ipmi_chassis_main(struct ipmi_intf * intf, int argc, char ** argv)
{ {
int rc = 0; int rc = 0;
if ((argc == 0) || (strncmp(argv[0], "help", 4) == 0)) { if ((argc == 0) || (strncmp(argv[0], "help", 4) == 0)) {
lprintf(LOG_NOTICE, "Chassis Commands: status, power, identify, policy, restart_cause, poh"); lprintf(LOG_NOTICE, "Chassis Commands: status, power, identify, policy, restart_cause, poh, bootdev, selftest");
} }
else if (strncmp(argv[0], "status", 6) == 0) { else if (strncmp(argv[0], "status", 6) == 0) {
rc = ipmi_chassis_status(intf); rc = ipmi_chassis_status(intf);
} }
else if (strncmp(argv[0], "selftest", 8) == 0) {
rc = ipmi_chassis_selftest(intf);
}
else if (strncmp(argv[0], "power", 5) == 0) { else if (strncmp(argv[0], "power", 5) == 0) {
uint8_t ctl = 0; uint8_t ctl = 0;
@ -546,7 +667,7 @@ ipmi_chassis_main(struct ipmi_intf * intf, int argc, char ** argv)
return 0; return 0;
} }
if (strncmp(argv[1], "status", 6) == 0) { if (strncmp(argv[1], "status", 6) == 0) {
rc = ipmi_chassis_power_status(intf); rc = ipmi_chassis_print_power_status(intf);
return rc; return rc;
} }
if ((strncmp(argv[1], "up", 2) == 0) || (strncmp(argv[1], "on", 2) == 0)) if ((strncmp(argv[1], "up", 2) == 0) || (strncmp(argv[1], "on", 2) == 0))
@ -611,9 +732,16 @@ ipmi_chassis_main(struct ipmi_intf * intf, int argc, char ** argv)
rc = ipmi_chassis_power_policy(intf, ctl); rc = ipmi_chassis_power_policy(intf, ctl);
} }
} }
else if (strncmp(argv[0], "bootparam", 7) == 0) { else if (strncmp(argv[0], "bootparam", 9) == 0) {
if ((argc < 3) || (strncmp(argv[1], "help", 4) == 0)) { if ((argc < 3) || (strncmp(argv[1], "help", 4) == 0)) {
lprintf(LOG_NOTICE, "bootparam get|set <option> [value ...]"); lprintf(LOG_NOTICE, "bootparam get <param #>");
lprintf(LOG_NOTICE, "bootparam set bootflag <flag>");
lprintf(LOG_NOTICE, " force_pxe : Force PXE boot");
lprintf(LOG_NOTICE, " force_disk : Force boot from default Hard-drive");
lprintf(LOG_NOTICE, " force_safe : Force boot from default Hard-drive, request Safe Mode");
lprintf(LOG_NOTICE, " force_diag : Force boot from Diagnostic Partition");
lprintf(LOG_NOTICE, " force_cdrom : Force boot from CD/DVD");
lprintf(LOG_NOTICE, " force_bios : Force boot into BIOS Setup");
} }
else { else {
if (strncmp(argv[1], "get", 3) == 0) { if (strncmp(argv[1], "get", 3) == 0) {
@ -624,7 +752,7 @@ ipmi_chassis_main(struct ipmi_intf * intf, int argc, char ** argv)
lprintf(LOG_NOTICE, "bootparam set <option> [value ...]"); lprintf(LOG_NOTICE, "bootparam set <option> [value ...]");
} else { } else {
if (strncmp(argv[2], "bootflag", 8) == 0) if (strncmp(argv[2], "bootflag", 8) == 0)
rc = ipmi_chassis_set_bootflag(intf, argv[3]); rc = ipmi_chassis_set_bootdev(intf, argv[3], 0);
else else
lprintf(LOG_NOTICE, "bootparam set <option> [value ...]"); lprintf(LOG_NOTICE, "bootparam set <option> [value ...]");
} }
@ -633,6 +761,29 @@ ipmi_chassis_main(struct ipmi_intf * intf, int argc, char ** argv)
lprintf(LOG_NOTICE, "bootparam get|set <option> [value ...]"); lprintf(LOG_NOTICE, "bootparam get|set <option> [value ...]");
} }
} }
else if (strncmp(argv[0], "bootdev", 7) == 0) {
if ((argc < 2) || (strncmp(argv[1], "help", 4) == 0)) {
lprintf(LOG_NOTICE, "bootdev <device> [clear-cmos=yes|no]");
lprintf(LOG_NOTICE, " none : Do not change boot device order");
lprintf(LOG_NOTICE, " pxe : Force PXE boot");
lprintf(LOG_NOTICE, " disk : Force boot from default Hard-drive");
lprintf(LOG_NOTICE, " safe : Force boot from default Hard-drive, request Safe Mode");
lprintf(LOG_NOTICE, " diag : Force boot from Diagnostic Partition");
lprintf(LOG_NOTICE, " cdrom : Force boot from CD/DVD");
lprintf(LOG_NOTICE, " bios : Force boot into BIOS Setup");
} else {
if (argc < 3)
rc = ipmi_chassis_set_bootdev(intf, argv[1], 0);
else if (strncmp(argv[2], "clear-cmos=", 11) == 0) {
if (strncmp(argv[2]+11, "yes", 3) == 0)
rc = ipmi_chassis_set_bootdev(intf, argv[1], 1);
else
rc = ipmi_chassis_set_bootdev(intf, argv[1], 0);
}
else
rc = ipmi_chassis_set_bootdev(intf, argv[1], 0);
}
}
else { else {
lprintf(LOG_ERR, "Invalid Chassis command: %s", argv[0]); lprintf(LOG_ERR, "Invalid Chassis command: %s", argv[0]);
return -1; return -1;

View File

@ -53,17 +53,42 @@
#include <ipmitool/ipmi_sel.h> #include <ipmitool/ipmi_sel.h>
#include <ipmitool/ipmi_strings.h> #include <ipmitool/ipmi_strings.h>
#include <ipmitool/ipmi_channel.h> #include <ipmitool/ipmi_channel.h>
#include <ipmitool/ipmi_event.h>
#include <ipmitool/ipmi_sdr.h>
static int static int
ipmi_send_platform_event(struct ipmi_intf * intf, int num) ipmi_event_msg_print(struct ipmi_intf * intf, struct platform_event_msg * pmsg)
{
struct sel_event_record sel_event;
memset(&sel_event, 0, sizeof(struct sel_event_record));
sel_event.record_id = 0;
sel_event.sel_type.standard_type.gen_id = 2;
sel_event.sel_type.standard_type.evm_rev = pmsg->evm_rev;
sel_event.sel_type.standard_type.sensor_type = pmsg->sensor_type;
sel_event.sel_type.standard_type.sensor_num = pmsg->sensor_num;
sel_event.sel_type.standard_type.event_type = pmsg->event_type;
sel_event.sel_type.standard_type.event_dir = pmsg->event_dir;
sel_event.sel_type.standard_type.event_data[0] = pmsg->event_data[0];
sel_event.sel_type.standard_type.event_data[1] = pmsg->event_data[1];
sel_event.sel_type.standard_type.event_data[2] = pmsg->event_data[2];
if (verbose)
ipmi_sel_print_extended_entry_verbose(intf, &sel_event);
else
ipmi_sel_print_extended_entry(intf, &sel_event);
}
static int
ipmi_send_platform_event(struct ipmi_intf * intf, struct platform_event_msg * emsg)
{ {
struct ipmi_rs * rsp; struct ipmi_rs * rsp;
struct ipmi_rq req; struct ipmi_rq req;
uint8_t rqdata[8]; uint8_t rqdata[8];
uint8_t chmed; uint8_t chmed;
int p = 0;
ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN);
memset(&req, 0, sizeof(req)); memset(&req, 0, sizeof(req));
memset(rqdata, 0, 8); memset(rqdata, 0, 8);
@ -71,53 +96,20 @@ ipmi_send_platform_event(struct ipmi_intf * intf, int num)
req.msg.netfn = IPMI_NETFN_SE; req.msg.netfn = IPMI_NETFN_SE;
req.msg.cmd = 0x02; req.msg.cmd = 0x02;
req.msg.data = rqdata; req.msg.data = rqdata;
req.msg.data_len = 7;
chmed = ipmi_current_channel_medium(intf); chmed = ipmi_current_channel_medium(intf);
if (chmed == IPMI_CHANNEL_MEDIUM_SYSTEM) { if (chmed == IPMI_CHANNEL_MEDIUM_SYSTEM) {
/* system interface, need extra generator ID */ /* system interface, need extra generator ID */
req.msg.data_len = 8; req.msg.data_len = 8;
rqdata[p++] = 0x20; rqdata[0] = 0x20;
memcpy(rqdata+1, emsg, sizeof(struct platform_event_msg));
}
else {
req.msg.data_len = 7;
memcpy(rqdata, emsg, sizeof(struct platform_event_msg));
} }
/* IPMB/LAN/etc */ ipmi_event_msg_print(intf, emsg);
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); rsp = intf->sendrecv(intf, &req);
if (rsp == NULL) { if (rsp == NULL) {
@ -133,6 +125,358 @@ ipmi_send_platform_event(struct ipmi_intf * intf, int num)
return 0; return 0;
} }
#define EVENT_THRESH_STATE_LNC_LO 0
#define EVENT_THRESH_STATE_LNC_HI 1
#define EVENT_THRESH_STATE_LCR_LO 2
#define EVENT_THRESH_STATE_LCR_HI 3
#define EVENT_THRESH_STATE_LNR_LO 4
#define EVENT_THRESH_STATE_LNR_HI 5
#define EVENT_THRESH_STATE_UNC_LO 6
#define EVENT_THRESH_STATE_UNC_HI 7
#define EVENT_THRESH_STATE_UCR_LO 8
#define EVENT_THRESH_STATE_UCR_HI 9
#define EVENT_THRESH_STATE_UNR_LO 10
#define EVENT_THRESH_STATE_UNR_HI 11
static const struct valstr ipmi_event_thresh_lo[] = {
{ EVENT_THRESH_STATE_LNC_LO, "lnc" },
{ EVENT_THRESH_STATE_LCR_LO, "lcr" },
{ EVENT_THRESH_STATE_LNR_LO, "lnr" },
{ EVENT_THRESH_STATE_UNC_LO, "unc" },
{ EVENT_THRESH_STATE_UCR_LO, "ucr" },
{ EVENT_THRESH_STATE_UNR_LO, "unr" },
{ 0, NULL },
};
static const struct valstr ipmi_event_thresh_hi[] = {
{ EVENT_THRESH_STATE_LNC_HI, "lnc" },
{ EVENT_THRESH_STATE_LCR_HI, "lcr" },
{ EVENT_THRESH_STATE_LNR_HI, "lnr" },
{ EVENT_THRESH_STATE_UNC_HI, "unc" },
{ EVENT_THRESH_STATE_UCR_HI, "ucr" },
{ EVENT_THRESH_STATE_UNR_HI, "unr" },
{ 0, NULL },
};
static int
ipmi_send_platform_event_num(struct ipmi_intf * intf, int num)
{
struct platform_event_msg emsg;
memset(&emsg, 0, sizeof(struct platform_event_msg));
/* IPMB/LAN/etc */
switch (num) {
case 1: /* temperature */
printf("Sending SAMPLE event: Temperature - "
"Upper Critical - Going High\n");
emsg.evm_rev = 0x04;
emsg.sensor_type = 0x01;
emsg.sensor_num = 0x30;
emsg.event_dir = EVENT_DIR_ASSERT;
emsg.event_type = 0x01;
emsg.event_data[0] = EVENT_THRESH_STATE_UCR_HI;
emsg.event_data[1] = 0xff;
emsg.event_data[2] = 0xff;
break;
case 2: /* voltage error */
printf("Sending SAMPLE event: Voltage Threshold - "
"Lower Critical - Going Low\n");
emsg.evm_rev = 0x04;
emsg.sensor_type = 0x02;
emsg.sensor_num = 0x60;
emsg.event_dir = EVENT_DIR_ASSERT;
emsg.event_type = 0x01;
emsg.event_data[0] = EVENT_THRESH_STATE_LCR_LO;
emsg.event_data[1] = 0xff;
emsg.event_data[2] = 0xff;
break;
case 3: /* correctable ECC */
printf("Sending SAMPLE event: Memory - Correctable ECC\n");
emsg.evm_rev = 0x04;
emsg.sensor_type = 0x0c;
emsg.sensor_num = 0x53;
emsg.event_dir = EVENT_DIR_ASSERT;
emsg.event_type = 0x6f;
emsg.event_data[0] = 0x00;
emsg.event_data[1] = 0xff;
emsg.event_data[2] = 0xff;
break;
default:
lprintf(LOG_ERR, "Invalid event number: %d", num);
return -1;
}
return ipmi_send_platform_event(intf, &emsg);
}
static int
ipmi_event_find_offset(uint8_t code,
struct ipmi_event_sensor_types * evt,
char * desc)
{
if (desc == NULL || code == 0)
return 0x00;
while (evt->type) {
if (evt->code == code && evt->desc != NULL &&
strncasecmp(desc, evt->desc, __maxlen(desc, evt->desc)) == 0)
return evt->offset;
evt++;
}
lprintf(LOG_WARN, "Unable to find matching event offset for '%s'", desc);
return -1;
}
static void
print_sensor_states(uint8_t sensor_type, uint8_t event_type)
{
printf("Sensor States: \n ");
ipmi_sdr_print_discrete_state_mini("\n ", sensor_type,
event_type, 0xff, 0xff);
printf("\n");
}
static int
ipmi_event_fromsensor(struct ipmi_intf * intf, char * id, char * state, char * evdir)
{
struct ipmi_rs * rsp;
struct sdr_record_list * sdr;
struct platform_event_msg emsg;
int off;
if (id == NULL) {
lprintf(LOG_ERR, "No sensor ID supplied");
return -1;
}
memset(&emsg, 0, sizeof(struct platform_event_msg));
emsg.evm_rev = 0x04;
if (evdir == NULL)
emsg.event_dir = EVENT_DIR_ASSERT;
else if (strncasecmp(evdir, "assert", 6) == 0)
emsg.event_dir = EVENT_DIR_ASSERT;
else if (strncasecmp(evdir, "deassert", 8) == 0)
emsg.event_dir = EVENT_DIR_DEASSERT;
else {
lprintf(LOG_ERR, "Invalid event direction %s. Must be 'assert' or 'deassert'", evdir);
return -1;
}
printf("Finding sensor %s... ", id);
sdr = ipmi_sdr_find_sdr_byid(intf, id);
if (sdr == NULL) {
printf("not found!\n");
return -1;
}
printf("ok\n");
switch (sdr->type)
{
case SDR_RECORD_TYPE_FULL_SENSOR:
emsg.sensor_type = sdr->record.full->sensor.type;
emsg.sensor_num = sdr->record.full->keys.sensor_num;
emsg.event_type = sdr->record.full->event_type;
break;
case SDR_RECORD_TYPE_COMPACT_SENSOR:
emsg.sensor_type = sdr->record.compact->sensor.type;
emsg.sensor_num = sdr->record.compact->keys.sensor_num;
emsg.event_type = sdr->record.compact->event_type;
break;
default:
lprintf(LOG_ERR, "Unknown sensor type for id '%s'", id);
return -1;
}
emsg.event_data[1] = 0xff;
emsg.event_data[2] = 0xff;
switch (emsg.event_type)
{
/*
* Threshold Class
*/
case 1:
{
int dir = 0;
int hilo = 0;
off = 1;
if (state == NULL || strncasecmp(state, "list", 4) == 0) {
printf("Sensor States:\n");
printf(" lnr : Lower Non-Recoverable \n");
printf(" lcr : Lower Critical\n");
printf(" lnc : Lower Non-Critical\n");
printf(" unc : Upper Non-Critical\n");
printf(" ucr : Upper Critical\n");
printf(" unr : Upper Non-Recoverable\n");
return -1;
}
if (0 != strncasecmp(state, "lnr", 3) &&
0 != strncasecmp(state, "lcr", 3) &&
0 != strncasecmp(state, "lnc", 3) &&
0 != strncasecmp(state, "unc", 3) &&
0 != strncasecmp(state, "ucr", 3) &&
0 != strncasecmp(state, "unr", 3))
{
lprintf(LOG_ERR, "Invalid threshold identifier %s", state);
return -1;
}
if (state[0] == 'u')
hilo = 1;
else
hilo = 0;
if (emsg.event_dir == EVENT_DIR_ASSERT)
dir = hilo;
else
dir = !hilo;
if ((emsg.event_dir == EVENT_DIR_ASSERT && hilo == 1) ||
(emsg.event_dir == EVENT_DIR_DEASSERT && hilo == 0))
emsg.event_data[0] = (uint8_t)(str2val(state, ipmi_event_thresh_hi) & 0xf);
else if ((emsg.event_dir == EVENT_DIR_ASSERT && hilo == 0) ||
(emsg.event_dir == EVENT_DIR_DEASSERT && hilo == 1))
emsg.event_data[0] = (uint8_t)(str2val(state, ipmi_event_thresh_lo) & 0xf);
else {
lprintf(LOG_ERR, "Invalid Event\n");
return -1;
}
rsp = ipmi_sdr_get_sensor_thresholds(intf, emsg.sensor_num);
if (rsp != NULL && rsp->ccode == 0) {
/* threshold reading */
emsg.event_data[2] = rsp->data[(emsg.event_data[0] / 2) + 1];
rsp = ipmi_sdr_get_sensor_hysteresis(intf, emsg.sensor_num);
if (rsp != NULL && rsp->ccode == 0)
off = dir ? rsp->data[0] : rsp->data[1];
if (off <= 0)
off = 1;
/* trigger reading */
if (dir) {
if ((emsg.event_data[2] + off) > 0xff)
emsg.event_data[1] = 0xff;
else
emsg.event_data[1] = emsg.event_data[2] + off;
}
else {
if ((emsg.event_data[2] - off) < 0)
emsg.event_data[1] = 0;
else
emsg.event_data[1] = emsg.event_data[2] - off;
}
/* trigger in byte 2, threshold in byte 3 */
emsg.event_data[0] |= 0x50;
}
}
break;
/*
* Digital Discrete
*/
case 3: case 4: case 5: case 6: case 8: case 9:
{
int x;
const char * digi_on[] = { "present", "assert", "limit",
"fail", "yes", "on", "up" };
const char * digi_off[] = { "absent", "deassert", "nolimit",
"nofail", "no", "off", "down" };
/*
* print list of available states for this sensor
*/
if (state == NULL || strncasecmp(state, "list", 4) == 0) {
print_sensor_states(emsg.sensor_type, emsg.event_type);
printf("Sensor State Shortcuts:\n");
for (x = 0; x < sizeof(digi_on)/sizeof(*digi_on); x++) {
printf(" %-9s %-9s\n", digi_on[x], digi_off[x]);
}
return 0;
}
off = 0;
for (x = 0; x < sizeof(digi_on)/sizeof(*digi_on); x++) {
if (strncasecmp(state, digi_on[x], strlen(digi_on[x])) == 0) {
emsg.event_data[0] = 1;
off = 1;
break;
}
else if (strncasecmp(state, digi_off[x], strlen(digi_off[x])) == 0) {
emsg.event_data[0] = 0;
off = 1;
break;
}
}
if (off == 0) {
off = ipmi_event_find_offset(
emsg.event_type, generic_event_types, state);
if (off < 0)
return -1;
emsg.event_data[0] = off;
}
}
break;
/*
* Generic Discrete
*/
case 2: case 7: case 10: case 11: case 12:
{
/*
* print list of available states for this sensor
*/
if (state == NULL || strncasecmp(state, "list", 4) == 0) {
print_sensor_states(emsg.sensor_type, emsg.event_type);
return 0;
}
off = ipmi_event_find_offset(
emsg.event_type, generic_event_types, state);
if (off < 0)
return -1;
emsg.event_data[0] = off;
}
break;
/*
* Sensor-Specific Discrete
*/
case 0x6f:
{
/*
* print list of available states for this sensor
*/
if (state == NULL || strncasecmp(state, "list", 4) == 0) {
print_sensor_states(emsg.sensor_type, emsg.event_type);
return 0;
}
off = ipmi_event_find_offset(
emsg.sensor_type, sensor_specific_types, state);
if (off < 0)
return -1;
emsg.event_data[0] = off;
}
break;
default:
return -1;
}
return ipmi_send_platform_event(intf, &emsg);
}
static int static int
ipmi_event_fromfile(struct ipmi_intf * intf, char * file) ipmi_event_fromfile(struct ipmi_intf * intf, char * file)
{ {
@ -150,9 +494,6 @@ ipmi_event_fromfile(struct ipmi_intf * intf, char * file)
if (file == NULL) if (file == NULL)
return -1; return -1;
/* must be admin privilege to do this */
ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN);
memset(rqdata, 0, 8); memset(rqdata, 0, 8);
/* setup Platform Event Message command */ /* setup Platform Event Message command */
@ -173,7 +514,7 @@ ipmi_event_fromfile(struct ipmi_intf * intf, char * file)
if (fp == NULL) if (fp == NULL)
return -1; return -1;
while (feof(fp) != 0) { while (feof(fp) == 0) {
if (fgets(buf, 1024, fp) == NULL) if (fgets(buf, 1024, fp) == NULL)
continue; continue;
@ -215,19 +556,19 @@ ipmi_event_fromfile(struct ipmi_intf * intf, char * file)
memset(&sel_event, 0, sizeof(struct sel_event_record)); memset(&sel_event, 0, sizeof(struct sel_event_record));
sel_event.record_id = 0; sel_event.record_id = 0;
sel_event.gen_id = 2; sel_event.sel_type.standard_type.gen_id = 2;
j = (chmed == IPMI_CHANNEL_MEDIUM_SYSTEM) ? 1 : 0; j = (chmed == IPMI_CHANNEL_MEDIUM_SYSTEM) ? 1 : 0;
sel_event.evm_rev = rqdata[j++]; sel_event.sel_type.standard_type.evm_rev = rqdata[j++];
sel_event.sensor_type = rqdata[j++]; sel_event.sel_type.standard_type.sensor_type = rqdata[j++];
sel_event.sensor_num = rqdata[j++]; sel_event.sel_type.standard_type.sensor_num = rqdata[j++];
sel_event.event_type = rqdata[j] & 0x7f; sel_event.sel_type.standard_type.event_type = rqdata[j] & 0x7f;
sel_event.event_dir = (rqdata[j++] & 0x80) >> 7; sel_event.sel_type.standard_type.event_dir = (rqdata[j++] & 0x80) >> 7;
sel_event.event_data[0] = rqdata[j++]; sel_event.sel_type.standard_type.event_data[0] = rqdata[j++];
sel_event.event_data[1] = rqdata[j++]; sel_event.sel_type.standard_type.event_data[1] = rqdata[j++];
sel_event.event_data[2] = rqdata[j++]; sel_event.sel_type.standard_type.event_data[2] = rqdata[j++];
ipmi_sel_print_std_entry(&sel_event); ipmi_sel_print_std_entry(intf, &sel_event);
rsp = intf->sendrecv(intf, &req); rsp = intf->sendrecv(intf, &req);
if (rsp == NULL) { if (rsp == NULL) {
@ -245,33 +586,56 @@ ipmi_event_fromfile(struct ipmi_intf * intf, char * file)
return rc; return rc;
} }
int static void
ipmi_event_main(struct ipmi_intf * intf, int argc, char ** argv) ipmi_event_usage(void)
{ {
uint8_t c; lprintf(LOG_NOTICE, "");
int rc = 0;
if (argc == 0 || strncmp(argv[0], "help", 4) == 0) {
lprintf(LOG_NOTICE, "usage: event <num>"); lprintf(LOG_NOTICE, "usage: event <num>");
lprintf(LOG_NOTICE, " Send generic test events");
lprintf(LOG_NOTICE, " 1 : Temperature - Upper Critical - Going High"); lprintf(LOG_NOTICE, " 1 : Temperature - Upper Critical - Going High");
lprintf(LOG_NOTICE, " 2 : Voltage Threshold - Lower Critical - Going Low"); lprintf(LOG_NOTICE, " 2 : Voltage Threshold - Lower Critical - Going Low");
lprintf(LOG_NOTICE, " 3 : Memory - Correctable ECC"); lprintf(LOG_NOTICE, " 3 : Memory - Correctable ECC");
lprintf(LOG_NOTICE, "");
lprintf(LOG_NOTICE, "usage: event file <filename>"); lprintf(LOG_NOTICE, "usage: event file <filename>");
lprintf(LOG_NOTICE, " Will read list of events from file"); lprintf(LOG_NOTICE, " Read and generate events from file");
return 0; lprintf(LOG_NOTICE, " Use the 'sel save' command to generate from SEL");
lprintf(LOG_NOTICE, "");
lprintf(LOG_NOTICE, "usage: event <sensorid> <state> [event_dir]");
lprintf(LOG_NOTICE, " sensorid : Sensor ID to use for event data");
lprintf(LOG_NOTICE, " state : Sensor state, use 'list' to see possible states for sensor");
lprintf(LOG_NOTICE, " event_dir : assert, deassert [default=assert]");
lprintf(LOG_NOTICE, "");
} }
int
ipmi_event_main(struct ipmi_intf * intf, int argc, char ** argv)
{
int rc = 0;
if (argc == 0 || strncmp(argv[0], "help", 4) == 0) {
ipmi_event_usage();
return 0;
}
if (strncmp(argv[0], "file", 4) == 0) { if (strncmp(argv[0], "file", 4) == 0) {
if (argc < 2) { if (argc < 2) {
lprintf(LOG_NOTICE, "usage: event file <filename>\n"); ipmi_event_usage();
rc = -1; return 0;
} else {
rc = ipmi_event_fromfile(intf, argv[1]);
} }
} else { return ipmi_event_fromfile(intf, argv[1]);
c = (uint8_t)strtol(argv[0], NULL, 0);
rc = ipmi_send_platform_event(intf, c);
} }
if (strlen(argv[0]) == 1) {
switch (argv[0][0]) {
case '1': return ipmi_send_platform_event_num(intf, 1);
case '2': return ipmi_send_platform_event_num(intf, 2);
case '3': return ipmi_send_platform_event_num(intf, 3);
}
}
if (argc < 2)
rc = ipmi_event_fromsensor(intf, argv[0], NULL, NULL);
else if (argc < 3)
rc = ipmi_event_fromsensor(intf, argv[0], argv[1], NULL);
else
rc = ipmi_event_fromsensor(intf, argv[0], argv[1], argv[2]);
return rc; return rc;
} }

File diff suppressed because it is too large Load Diff

1138
ipmitool/lib/ipmi_fwum.c Normal file

File diff suppressed because it is too large Load Diff

195
ipmitool/lib/ipmi_isol.c Normal file
View File

@ -0,0 +1,195 @@
/*
* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistribution of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistribution in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind.
* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
* SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE
* FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
* SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
* OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
* PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
* LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed or intended for use
* in the design, construction, operation or maintenance of any nuclear
* facility.
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ipmitool/helper.h>
#include <ipmitool/log.h>
#include <ipmitool/ipmi.h>
#include <ipmitool/ipmi_strings.h>
#include <ipmitool/ipmi_intf.h>
#include <ipmitool/ipmi_isol.h>
const struct valstr ipmi_isol_baud_vals[] = {
{ ISOL_BAUD_RATE_9600, "9600" },
{ ISOL_BAUD_RATE_19200, "19200" },
{ ISOL_BAUD_RATE_38400, "38400" },
{ ISOL_BAUD_RATE_57600, "57600" },
{ ISOL_BAUD_RATE_115200, "115200" },
{ 0x00, NULL }
};
extern int verbose;
static int ipmi_isol_setup(struct ipmi_intf * intf, char baudsetting)
{
struct ipmi_rs * rsp;
struct ipmi_rq req;
unsigned char data[6];
/* TEST FOR AVAILABILITY */
memset(data, 0, 6);
data[0] = 0x00;
data[1] = ISOL_ENABLE_PARAM;
data[2] = ISOL_ENABLE_FLAG;
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_ISOL;
req.msg.cmd = SET_ISOL_CONFIG;
req.msg.data = data;
req.msg.data_len = 3;
rsp = intf->sendrecv(intf, &req);
if (rsp == NULL) {
lprintf(LOG_ERR, "Error in Set ISOL Config Command");
return -1;
}
if (rsp->ccode == 0xc1) {
lprintf(LOG_ERR, "IPMI v1.5 Serial Over Lan (ISOL) not supported!");
return -1;
}
if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Error in Set ISOL Config Command: %s",
val2str(rsp->ccode, completion_code_vals));
return -1;
}
/* GET ISOL CONFIG */
memset(data, 0, 6);
data[0] = 0x00;
data[1] = ISOL_AUTHENTICATION_PARAM;
data[2] = 0x00; /* block */
data[3] = 0x00; /* selector */
req.msg.cmd = GET_ISOL_CONFIG;
req.msg.data_len = 4;
rsp = intf->sendrecv(intf, &req);
if (rsp == NULL) {
lprintf(LOG_ERR, "Error in Get ISOL Config Command");
return -1;
}
if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Error in Get ISOL Config Command: %s",
val2str(rsp->ccode, completion_code_vals));
return -1;
}
if (verbose > 1)
printbuf(rsp->data, rsp->data_len, "ISOL Config");
/* SET ISOL CONFIG - AUTHENTICATION */
memset(data, 0, 6);
data[0] = 0x00;
data[1] = ISOL_AUTHENTICATION_PARAM;
data[2] = ISOL_PRIVILEGE_LEVEL_USER | (rsp->data[1] & 0x80);
req.msg.cmd = SET_ISOL_CONFIG;
req.msg.data_len = 3;
rsp = intf->sendrecv(intf, &req);
if (rsp == NULL) {
lprintf(LOG_ERR, "Error in Set ISOL Config (Authentication) Command");
return -1;
}
if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Error in Set ISOL Config (Authentication) Command: %s",
val2str(rsp->ccode, completion_code_vals));
return -1;
}
/* SET ISOL CONFIG - BAUD RATE */
memset(data, 0, 6);
data[0] = 0x00;
data[1] = ISOL_BAUD_RATE_PARAM;
data[2] = baudsetting;
req.msg.cmd = SET_ISOL_CONFIG;
req.msg.data_len = 3;
rsp = intf->sendrecv(intf, &req);
if (rsp == NULL) {
lprintf(LOG_ERR, "Error in Set ISOL Config (Baud Rate) Command");
return -1;
}
if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Error in Set ISOL Config (Baud Rate) Command: %s",
val2str(rsp->ccode, completion_code_vals));
return -1;
}
printf("Set ISOL Baud Rate to %s\n",
val2str(baudsetting, ipmi_isol_baud_vals));
return 0;
}
int ipmi_isol_main(struct ipmi_intf * intf, int argc, char ** argv)
{
int ret = 0;
if (argc < 2 || strncmp(argv[0], "help", 4) == 0) {
lprintf(LOG_NOTICE, "ISOL Commands: setup <baud>");
lprintf(LOG_NOTICE, "ISOL Baud Rates: 9600, 19200, 38400, 57600, 115200");
return 0;
}
if (strncmp(argv[0], "setup", 5) == 0) {
if (strncmp(argv[1], "9600", 4) == 0) {
ret = ipmi_isol_setup(intf, ISOL_BAUD_RATE_9600);
}
else if (strncmp(argv[1], "19200", 5) == 0) {
ret = ipmi_isol_setup(intf, ISOL_BAUD_RATE_19200);
}
else if (strncmp(argv[1], "38400", 5) == 0) {
ret = ipmi_isol_setup(intf, ISOL_BAUD_RATE_38400);
}
else if (strncmp(argv[1], "57600", 5) == 0) {
ret = ipmi_isol_setup(intf, ISOL_BAUD_RATE_57600);
}
else if (strncmp(argv[1], "115200", 6) == 0) {
ret = ipmi_isol_setup(intf, ISOL_BAUD_RATE_115200);
}
else {
lprintf(LOG_ERR, "ISOL - Unsupported baud rate: %s", argv[1]);
ret = -1;
}
}
return ret;
}

File diff suppressed because it is too large Load Diff

616
ipmitool/lib/ipmi_main.c Normal file
View File

@ -0,0 +1,616 @@
/*
* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistribution of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistribution in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind.
* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
* SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE
* FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
* SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
* OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
* PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
* LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed or intended for use
* in the design, construction, operation or maintenance of any nuclear
* facility.
*/
#include <stdlib.h>
#include <stdio.h>
#include <inttypes.h>
#include <signal.h>
#include <string.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <ctype.h>
#include <ipmitool/helper.h>
#include <ipmitool/log.h>
#include <ipmitool/ipmi.h>
#include <ipmitool/ipmi_intf.h>
#include <ipmitool/ipmi_session.h>
#include <ipmitool/ipmi_sdr.h>
#include <ipmitool/ipmi_sel.h>
#include <ipmitool/ipmi_fru.h>
#include <ipmitool/ipmi_sol.h>
#include <ipmitool/ipmi_isol.h>
#include <ipmitool/ipmi_lanp.h>
#include <ipmitool/ipmi_chassis.h>
#include <ipmitool/ipmi_mc.h>
#include <ipmitool/ipmi_sensor.h>
#include <ipmitool/ipmi_channel.h>
#include <ipmitool/ipmi_session.h>
#include <ipmitool/ipmi_event.h>
#include <ipmitool/ipmi_user.h>
#include <ipmitool/ipmi_raw.h>
#include <ipmitool/ipmi_pef.h>
#include <ipmitool/ipmi_oem.h>
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#ifdef ENABLE_ALL_OPTIONS
# define OPTION_STRING "I:hVvcgsEao:H:P:f:U:p:C:L:A:t:m:S:l:b:e:k:"
#else
# define OPTION_STRING "I:hVvcH:f:U:p:S:"
#endif
extern int verbose;
extern int csv_output;
extern const struct valstr ipmi_privlvl_vals[];
extern const struct valstr ipmi_authtype_session_vals[];
/* defined in ipmishell.c */
#ifdef HAVE_READLINE
extern int ipmi_shell_main(struct ipmi_intf * intf, int argc, char ** argv);
#endif
extern int ipmi_set_main(struct ipmi_intf * intf, int argc, char ** argv);
extern int ipmi_exec_main(struct ipmi_intf * intf, int argc, char ** argv);
/* ipmi_password_file_read - Open file and read password from it
*
* @filename: file name to read from
*
* returns pointer to allocated buffer containing password
* (caller is expected to free when finished)
* returns NULL on error
*/
static char *
ipmi_password_file_read(char * filename)
{
FILE * fp;
char * pass = NULL;
int l;
pass = malloc(16);
if (pass == NULL) {
lprintf(LOG_ERR, "ipmitool: malloc failure");
return NULL;
}
fp = ipmi_open_file_read((const char *)filename);
if (fp == NULL) {
lprintf(LOG_ERR, "Unable to open password file %s",
filename);
return NULL;
}
/* read in id */
if (fgets(pass, 16, fp) == NULL) {
lprintf(LOG_ERR, "Unable to read password from file %s",
filename);
fclose(fp);
return NULL;
}
/* remove trailing whitespace */
l = strcspn(pass, " \r\n\t");
if (l > 0) {
pass[l] = '\0';
}
fclose(fp);
return pass;
}
/*
* Print all the commands in the above table to stderr
* used for help text on command line and shell
*/
void
ipmi_cmd_print(struct ipmi_cmd * cmdlist)
{
struct ipmi_cmd * cmd;
int hdr = 0;
if (cmdlist == NULL)
return;
for (cmd=cmdlist; cmd->func != NULL; cmd++) {
if (cmd->desc == NULL)
continue;
if (hdr == 0) {
lprintf(LOG_NOTICE, "Commands:");
hdr = 1;
}
lprintf(LOG_NOTICE, "\t%-12s %s", cmd->name, cmd->desc);
}
lprintf(LOG_NOTICE, "");
}
/* ipmi_cmd_run - run a command from list based on parameters
* called from main()
*
* 1. iterate through ipmi_cmd_list matching on name
* 2. call func() for that command
*
* @intf: ipmi interface
* @name: command name
* @argc: command argument count
* @argv: command argument list
*
* returns value from func() of that commnad if found
* returns -1 if command is not found
*/
int
ipmi_cmd_run(struct ipmi_intf * intf, char * name, int argc, char ** argv)
{
struct ipmi_cmd * cmd = intf->cmdlist;
/* hook to run a default command if nothing specified */
if (name == NULL) {
if (cmd->func == NULL || cmd->name == NULL)
return -1;
else if (strncmp(cmd->name, "default", 7) == 0)
return cmd->func(intf, 0, NULL);
else {
lprintf(LOG_ERR, "No command provided!");
ipmi_cmd_print(intf->cmdlist);
return -1;
}
}
for (cmd=intf->cmdlist; cmd->func != NULL; cmd++) {
if (strncmp(name, cmd->name, __maxlen(cmd->name, name)) == 0)
break;
}
if (cmd->func == NULL) {
cmd = intf->cmdlist;
if (strncmp(cmd->name, "default", 7) == 0)
return cmd->func(intf, argc+1, argv-1);
lprintf(LOG_ERR, "Invalid command: %s", name);
ipmi_cmd_print(intf->cmdlist);
return -1;
}
return cmd->func(intf, argc, argv);
}
static void
ipmi_option_usage(const char * progname, struct ipmi_cmd * cmdlist, struct ipmi_intf_support * intflist)
{
lprintf(LOG_NOTICE, "%s version %s\n", progname, VERSION);
lprintf(LOG_NOTICE, "usage: %s [options...] <command>\n", progname);
lprintf(LOG_NOTICE, " -h This help");
lprintf(LOG_NOTICE, " -V Show version information");
lprintf(LOG_NOTICE, " -v Verbose (can use multiple times)");
lprintf(LOG_NOTICE, " -c Display output in comma separated format");
lprintf(LOG_NOTICE, " -I intf Interface to use");
lprintf(LOG_NOTICE, " -H hostname Remote host name for LAN interface");
lprintf(LOG_NOTICE, " -p port Remote RMCP port [default=623]");
lprintf(LOG_NOTICE, " -U username Remote session username");
lprintf(LOG_NOTICE, " -f file Read remote session password from file");
lprintf(LOG_NOTICE, " -S sdr Use local file for remote SDR cache");
#ifdef ENABLE_ALL_OPTIONS
lprintf(LOG_NOTICE, " -a Prompt for remote password");
lprintf(LOG_NOTICE, " -e char Set SOL escape character");
lprintf(LOG_NOTICE, " -C ciphersuite Cipher suite to be used by lanplus interface");
lprintf(LOG_NOTICE, " -k key Use Kg key for IPMIv2 authentication");
lprintf(LOG_NOTICE, " -L level Remote session privilege level [default=ADMINISTRATOR]");
lprintf(LOG_NOTICE, " -A authtype Force use of auth type NONE, PASSWORD, MD2, MD5 or OEM");
lprintf(LOG_NOTICE, " -P password Remote session password");
lprintf(LOG_NOTICE, " -E Read password from IPMI_PASSWORD environment variable");
lprintf(LOG_NOTICE, " -m address Set local IPMB address");
lprintf(LOG_NOTICE, " -b channel Set destination channel for bridged request");
lprintf(LOG_NOTICE, " -l lun Set destination lun for raw commands");
lprintf(LOG_NOTICE, " -t address Bridge request to remote target address");
lprintf(LOG_NOTICE, " -o oemtype Setup for OEM (use 'list' to see available OEM types)");
#endif
lprintf(LOG_NOTICE, "");
ipmi_intf_print(intflist);
if (cmdlist != NULL)
ipmi_cmd_print(cmdlist);
}
/* ipmi_parse_options - helper function to handle parsing command line options
*
* @argc: count of options
* @argv: list of options
* @cmdlist: list of supported commands
* @intflist: list of supported interfaces
*
* returns 0 on success
* returns -1 on error
*/
int
ipmi_main(int argc, char ** argv,
struct ipmi_cmd * cmdlist,
struct ipmi_intf_support * intflist)
{
struct ipmi_intf * intf = NULL;
struct ipmi_intf_support * sup;
int privlvl = 0;
uint8_t target_addr = 0;
uint8_t target_channel = 0;
uint8_t target_lun = 0;
uint8_t my_addr = 0;
int authtype = -1;
char * tmp = NULL;
char * hostname = NULL;
char * username = NULL;
char * password = NULL;
char * intfname = NULL;
char * progname = NULL;
char * oemtype = NULL;
char * sdrcache = NULL;
char * kgkey = NULL;
int port = 0;
int cipher_suite_id = 3; /* See table 22-19 of the IPMIv2 spec */
int argflag, i, found;
int rc = -1;
char sol_escape_char = SOL_ESCAPE_CHARACTER_DEFAULT;
/* save program name */
progname = strrchr(argv[0], '/');
progname = ((progname == NULL) ? argv[0] : progname+1);
while ((argflag = getopt(argc, (char **)argv, OPTION_STRING)) != -1)
{
switch (argflag) {
case 'I':
intfname = strdup(optarg);
if (intfname == NULL) {
lprintf(LOG_ERR, "%s: malloc failure", progname);
goto out_free;
}
if (intflist != NULL) {
found = 0;
for (sup=intflist; sup->name != NULL; sup++) {
if (strncmp(sup->name, intfname, strlen(intfname)) == 0 &&
strncmp(sup->name, intfname, strlen(sup->name)) == 0 &&
sup->supported == 1)
found = 1;
}
if (!found) {
lprintf(LOG_ERR, "Interface %s not supported", intfname);
goto out_free;
}
}
break;
case 'h':
ipmi_option_usage(progname, cmdlist, intflist);
rc = 0;
goto out_free;
break;
case 'V':
printf("%s version %s\n", progname, VERSION);
rc = 0;
goto out_free;
break;
case 'p':
port = atoi(optarg);
break;
case 'C':
cipher_suite_id = atoi(optarg);
break;
case 'v':
verbose++;
break;
case 'c':
csv_output = 1;
break;
case 'H':
hostname = strdup(optarg);
if (hostname == NULL) {
lprintf(LOG_ERR, "%s: malloc failure", progname);
goto out_free;
}
break;
case 'f':
if (password)
free(password);
password = ipmi_password_file_read(optarg);
if (password == NULL)
lprintf(LOG_ERR, "Unable to read password "
"from file %s", optarg);
break;
case 'a':
#ifdef HAVE_GETPASSPHRASE
tmp = getpassphrase("Password: ");
#else
tmp = getpass("Password: ");
#endif
if (tmp != NULL) {
if (password)
free(password);
password = strdup(tmp);
if (password == NULL) {
lprintf(LOG_ERR, "%s: malloc failure", progname);
goto out_free;
}
}
break;
case 'k':
kgkey = strdup(optarg);
if (kgkey == NULL) {
lprintf(LOG_ERR, "%s: malloc failure", progname);
goto out_free;
}
break;
case 'U':
username = strdup(optarg);
if (username == NULL) {
lprintf(LOG_ERR, "%s: malloc failure", progname);
goto out_free;
}
break;
case 'S':
sdrcache = strdup(optarg);
if (sdrcache == NULL) {
lprintf(LOG_ERR, "%s: malloc failure", progname);
goto out_free;
}
break;
#ifdef ENABLE_ALL_OPTIONS
case 'o':
oemtype = strdup(optarg);
if (oemtype == NULL) {
lprintf(LOG_ERR, "%s: malloc failure", progname);
goto out_free;
}
if (strncmp(oemtype, "list", 4) == 0 ||
strncmp(oemtype, "help", 4) == 0) {
ipmi_oem_print();
goto out_free;
}
break;
case 'g':
/* backwards compatible oem hack */
oemtype = strdup("intelwv2");
break;
case 's':
/* backwards compatible oem hack */
oemtype = strdup("supermicro");
break;
case 'P':
if (password)
free(password);
password = strdup(optarg);
if (password == NULL) {
lprintf(LOG_ERR, "%s: malloc failure", progname);
goto out_free;
}
/* Prevent password snooping with ps */
i = strlen(optarg);
memset(optarg, 'X', i);
break;
case 'E':
if ((tmp = getenv("IPMITOOL_PASSWORD")))
{
if (password)
free(password);
password = strdup(tmp);
if (password == NULL) {
lprintf(LOG_ERR, "%s: malloc failure", progname);
goto out_free;
}
}
else if ((tmp = getenv("IPMI_PASSWORD")))
{
if (password)
free(password);
password = strdup(tmp);
if (password == NULL) {
lprintf(LOG_ERR, "%s: malloc failure", progname);
goto out_free;
}
}
else {
lprintf(LOG_WARN, "Unable to read password from environment");
}
break;
case 'L':
privlvl = str2val(optarg, ipmi_privlvl_vals);
if (privlvl == 0xFF)
lprintf(LOG_WARN, "Invalid privilege level %s", optarg);
break;
case 'A':
authtype = str2val(optarg, ipmi_authtype_session_vals);
break;
case 't':
target_addr = (uint8_t)strtol(optarg, NULL, 0);
break;
case 'b':
target_channel = (uint8_t)strtol(optarg, NULL, 0);
break;
case 'l':
target_lun = (uint8_t)strtol(optarg, NULL, 0);
break;
case 'm':
my_addr = (uint8_t)strtol(optarg, NULL, 0);
break;
case 'e':
sol_escape_char = optarg[0];
break;
#endif
default:
ipmi_option_usage(progname, cmdlist, intflist);
goto out_free;
}
}
/* check for command before doing anything */
if (argc-optind > 0 &&
strncmp(argv[optind], "help", 4) == 0) {
ipmi_cmd_print(cmdlist);
rc = 0;
goto out_free;
}
/*
* If the user has specified a hostname (-H option)
* then this is a remote access session.
*
* If no password was specified by any other method
* and the authtype was not explicitly set to NONE
* then prompt the user.
*/
if (hostname != NULL && password == NULL &&
(authtype != IPMI_SESSION_AUTHTYPE_NONE || authtype < 0)) {
#ifdef HAVE_GETPASSPHRASE
tmp = getpassphrase("Password: ");
#else
tmp = getpass("Password: ");
#endif
if (tmp != NULL) {
password = strdup(tmp);
if (password == NULL) {
lprintf(LOG_ERR, "%s: malloc failure", progname);
goto out_free;
}
}
}
/* if no interface was specified but a
* hostname was then use LAN by default
* otherwise the default is hardcoded
* to use the first entry in the list
*/
if (intfname == NULL && hostname != NULL) {
intfname = strdup("lan");
if (intfname == NULL) {
lprintf(LOG_ERR, "%s: malloc failure", progname);
goto out_free;
}
}
/* load interface */
intf = ipmi_intf_load(intfname);
if (intf == NULL) {
lprintf(LOG_ERR, "Error loading interface %s", intfname);
goto out_free;
}
/* setup log */
log_init(progname, 0, verbose);
/* run OEM setup if found */
if (oemtype != NULL &&
ipmi_oem_setup(intf, oemtype) < 0) {
lprintf(LOG_ERR, "OEM setup for \"%s\" failed", oemtype);
goto out_free;
}
/* set session variables */
if (hostname != NULL)
ipmi_intf_session_set_hostname(intf, hostname);
if (username != NULL)
ipmi_intf_session_set_username(intf, username);
if (password != NULL)
ipmi_intf_session_set_password(intf, password);
if (kgkey != NULL)
ipmi_intf_session_set_kgkey(intf, kgkey);
if (port > 0)
ipmi_intf_session_set_port(intf, port);
if (authtype >= 0)
ipmi_intf_session_set_authtype(intf, (uint8_t)authtype);
if (privlvl > 0)
ipmi_intf_session_set_privlvl(intf, (uint8_t)privlvl);
else
ipmi_intf_session_set_privlvl(intf,
IPMI_SESSION_PRIV_ADMIN); /* default */
ipmi_intf_session_set_sol_escape_char(intf, sol_escape_char);
ipmi_intf_session_set_cipher_suite_id(intf, cipher_suite_id);
/* setup destination lun if given */
intf->target_lun = target_lun ;
/* setup destination channel if given */
intf->target_channel = target_channel ;
/* setup IPMB local and target address if given */
intf->my_addr = my_addr ? : IPMI_BMC_SLAVE_ADDR;
if (target_addr > 0) {
/* need to open the interface first */
if (intf->open != NULL)
intf->open(intf);
intf->target_addr = target_addr;
/* must be admin level to do this over lan */
ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN);
}
/* parse local SDR cache if given */
if (sdrcache != NULL) {
ipmi_sdr_list_cache_fromfile(intf, sdrcache);
}
intf->cmdlist = cmdlist;
/* now we finally run the command */
if (argc-optind > 0)
rc = ipmi_cmd_run(intf, argv[optind], argc-optind-1, &(argv[optind+1]));
else
rc = ipmi_cmd_run(intf, NULL, 0, NULL);
/* clean repository caches */
ipmi_cleanup(intf);
/* call interface close function if available */
if (intf->opened > 0 && intf->close != NULL)
intf->close(intf);
out_free:
log_halt();
if (intfname != NULL)
free(intfname);
if (hostname != NULL)
free(hostname);
if (username != NULL)
free(username);
if (password != NULL)
free(password);
if (oemtype != NULL)
free(oemtype);
return rc;
}

View File

@ -37,9 +37,11 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <time.h>
#include <ipmitool/helper.h> #include <ipmitool/helper.h>
#include <ipmitool/log.h> #include <ipmitool/log.h>
#include <ipmitool/bswap.h>
#include <ipmitool/ipmi.h> #include <ipmitool/ipmi.h>
#include <ipmitool/ipmi_intf.h> #include <ipmitool/ipmi_intf.h>
#include <ipmitool/ipmi_mc.h> #include <ipmitool/ipmi_mc.h>
@ -63,21 +65,23 @@ ipmi_mc_reset(struct ipmi_intf * intf, int cmd)
struct ipmi_rs * rsp; struct ipmi_rs * rsp;
struct ipmi_rq req; struct ipmi_rq req;
intf->open(intf);
memset(&req, 0, sizeof(req)); memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_APP; req.msg.netfn = IPMI_NETFN_APP;
req.msg.cmd = cmd; req.msg.cmd = cmd;
req.msg.data_len = 0; req.msg.data_len = 0;
if (cmd == BMC_COLD_RESET)
intf->noanswer = 1;
rsp = intf->sendrecv(intf, &req); rsp = intf->sendrecv(intf, &req);
if (rsp == NULL) {
lprintf(LOG_ERR, "Reset command failed"); if (cmd == BMC_COLD_RESET)
return -1; intf->abort = 1;
}
if (rsp->ccode > 0) { printf("Sent %s reset command to MC\n",
lprintf(LOG_ERR, "Reset command failed: %s", (cmd == BMC_WARM_RESET) ? "warm" : "cold");
val2str(rsp->ccode, completion_code_vals));
return -1;
}
return 0; return 0;
} }
@ -150,12 +154,13 @@ struct bitfield_data mc_enables_bf[] = {
}; };
static void static void
printf_mc_usage() printf_mc_usage(void)
{ {
struct bitfield_data * bf; struct bitfield_data * bf;
printf("MC Commands:\n"); printf("MC Commands:\n");
printf(" reset <warm|cold>\n"); printf(" reset <warm|cold>\n");
printf(" info\n"); printf(" info\n");
printf(" selftest\n");
printf(" getenables\n"); printf(" getenables\n");
printf(" setenables <option=on|off> ...\n"); printf(" setenables <option=on|off> ...\n");
@ -219,8 +224,6 @@ ipmi_mc_set_enables(struct ipmi_intf * intf, int argc, char ** argv)
uint8_t en; uint8_t en;
int i; int i;
ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN);
if (argc < 1 || strncmp(argv[0], "help", 4) == 0) { if (argc < 1 || strncmp(argv[0], "help", 4) == 0) {
printf_mc_usage(); printf_mc_usage();
return 0; return 0;
@ -345,6 +348,10 @@ ipmi_mc_get_deviceid(struct ipmi_intf * intf)
IPM_DEV_IPMI_VERSION_MINOR(devid->ipmi_version)); IPM_DEV_IPMI_VERSION_MINOR(devid->ipmi_version));
printf("Manufacturer ID : %lu\n", printf("Manufacturer ID : %lu\n",
(long)IPM_DEV_MANUFACTURER_ID(devid->manufacturer_id)); (long)IPM_DEV_MANUFACTURER_ID(devid->manufacturer_id));
printf("Manufacturer Name : %s\n",
val2str( (long)IPM_DEV_MANUFACTURER_ID(devid->manufacturer_id),
ipmi_oem_info) );
printf("Product ID : %u (0x%02x%02x)\n", printf("Product ID : %u (0x%02x%02x)\n",
buf2short((uint8_t *)(devid->product_id)), buf2short((uint8_t *)(devid->product_id)),
devid->product_id[1], devid->product_id[0]); devid->product_id[1], devid->product_id[0]);
@ -370,6 +377,154 @@ ipmi_mc_get_deviceid(struct ipmi_intf * intf)
return 0; return 0;
} }
struct ipmi_guid {
uint32_t time_low; /* timestamp low field */
uint16_t time_mid; /* timestamp middle field */
uint16_t time_hi_and_version; /* timestamp high field and version number */
uint8_t clock_seq_hi_variant;/* clock sequence high field and variant */
uint8_t clock_seq_low; /* clock sequence low field */
uint8_t node[6]; /* node */
} __attribute__((packed));
/* ipmi_mc_get_guid - print this MC GUID
*
* @intf: ipmi interface
*
* returns 0 on success
* returns -1 on error
*/
static int
ipmi_mc_get_guid(struct ipmi_intf * intf)
{
struct ipmi_rs * rsp;
struct ipmi_rq req;
struct ipmi_guid guid;
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_APP;
req.msg.cmd = BMC_GET_GUID;
rsp = intf->sendrecv(intf, &req);
if (rsp == NULL) {
lprintf(LOG_ERR, "Get GUID command failed");
return -1;
}
if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Get GUID command failed: %s",
val2str(rsp->ccode, completion_code_vals));
return -1;
}
if (rsp->data_len == sizeof(struct ipmi_guid)) {
uint8_t tbuf[40];
time_t s;
memset(tbuf, 0, 40);
memset(&guid, 0, sizeof(struct ipmi_guid));
memcpy(&guid, rsp->data, rsp->data_len);
printf("System GUID : %08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x\n",
guid.time_low, guid.time_mid, guid.time_hi_and_version,
guid.clock_seq_hi_variant << 8 | guid.clock_seq_low,
guid.node[5], guid.node[4], guid.node[3],
guid.node[2], guid.node[1], guid.node[0]);
s = (time_t)BSWAP_32(guid.time_low);
strftime(tbuf, sizeof(tbuf), "%m/%d/%Y %H:%M:%S", localtime(&s));
printf("Timestamp : %s\n", tbuf);
}
else {
lprintf(LOG_ERR, "Invalid GUID length %d", rsp->data_len);
}
return 0;
}
/* ipmi_mc_get_selftest - returns and print selftest results
*
* @intf: ipmi interface
*/
static int ipmi_mc_get_selftest(struct ipmi_intf * intf)
{
int rv = 0;
struct ipmi_rs * rsp;
struct ipmi_rq req;
struct ipm_selftest_rsp *sft_res;
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_APP;
req.msg.cmd = BMC_GET_SELF_TEST;
req.msg.data_len = 0;
rsp = intf->sendrecv(intf, &req);
if (!rsp) {
lprintf(LOG_ERR, "No response from devices\n");
return -1;
}
if (rsp->ccode) {
lprintf(LOG_ERR, "Bad response: (%s)",
val2str(rsp->ccode, completion_code_vals));
return -1;
}
sft_res = (struct ipm_selftest_rsp *) rsp->data;
if (sft_res->code == IPM_SFT_CODE_OK) {
printf("Selftest: passed\n");
rv = 0;
}
else if (sft_res->code == IPM_SFT_CODE_NOT_IMPLEMENTED) {
printf("Selftest: not implemented\n");
rv = -1;
}
else if (sft_res->code == IPM_SFT_CODE_DEV_CORRUPTED) {
printf("Selftest: device corrupted\n");
rv = -1;
if (sft_res->test & IPM_SELFTEST_SEL_ERROR) {
printf(" -> SEL device not accessible\n");
}
if (sft_res->test & IPM_SELFTEST_SDR_ERROR) {
printf(" -> SDR repository not accesible\n");
}
if (sft_res->test & IPM_SELFTEST_FRU_ERROR) {
printf("FRU device not accessible\n");
}
if (sft_res->test & IPM_SELFTEST_IPMB_ERROR) {
printf("IPMB signal lines do not respond\n");
}
if (sft_res->test & IPM_SELFTEST_SDRR_EMPTY) {
printf("SDR repository empty\n");
}
if (sft_res->test & IPM_SELFTEST_INTERNAL_USE) {
printf("Internal Use Area corrupted\n");
}
if (sft_res->test & IPM_SELFTEST_FW_BOOTBLOCK) {
printf("Controller update boot block corrupted\n");
}
if (sft_res->test & IPM_SELFTEST_FW_CORRUPTED) {
printf("controller operational firmware corrupted\n");
}
}
else if (sft_res->code == IPM_SFT_CODE_FATAL_ERROR) {
printf("Selftest : fatal error\n");
printf("Failure code : %02x\n", sft_res->test);
rv = -1;
}
else if (sft_res->code == IPM_SFT_CODE_RESERVED) {
printf("Selftest: N/A");
rv = -1;
}
else {
printf("Selttest : device specific\n");
printf("Failure code : %02x\n", sft_res->test);
rv = 0;
}
return rv;
}
/* ipmi_mc_main - top-level handler for MC functions /* ipmi_mc_main - top-level handler for MC functions
* *
* @intf: ipmi interface * @intf: ipmi interface
@ -404,12 +559,18 @@ ipmi_mc_main(struct ipmi_intf * intf, int argc, char ** argv)
else if (strncmp(argv[0], "info", 4) == 0) { else if (strncmp(argv[0], "info", 4) == 0) {
rc = ipmi_mc_get_deviceid(intf); rc = ipmi_mc_get_deviceid(intf);
} }
else if (strncmp(argv[0], "guid", 4) == 0) {
rc = ipmi_mc_get_guid(intf);
}
else if (strncmp(argv[0], "getenables", 10) == 0) { else if (strncmp(argv[0], "getenables", 10) == 0) {
rc = ipmi_mc_get_enables(intf); rc = ipmi_mc_get_enables(intf);
} }
else if (strncmp(argv[0], "setenables", 10) == 0) { else if (strncmp(argv[0], "setenables", 10) == 0) {
rc = ipmi_mc_set_enables(intf, argc-1, &(argv[1])); rc = ipmi_mc_set_enables(intf, argc-1, &(argv[1]));
} }
else if (!strncmp(argv[0], "selftest", 8)) {
rc = ipmi_mc_get_selftest(intf);
}
return rc; return rc;
} }

View File

@ -45,12 +45,20 @@ static int ipmi_oem_supermicro(struct ipmi_intf * intf);
static struct ipmi_oem_handle ipmi_oem_list[] = { static struct ipmi_oem_handle ipmi_oem_list[] = {
{ {
name: "supermicro", name: "supermicro",
desc: "Supermicro BMC with OEM LAN authentication support", desc: "Supermicro IPMIv1.5 BMC with OEM LAN authentication support",
setup: ipmi_oem_supermicro, setup: ipmi_oem_supermicro,
}, },
{ {
name: "intelwv2", name: "intelwv2",
desc: "Intel SE7501WV2 BMC with extra LAN communication support", desc: "Intel SE7501WV2 IPMIv1.5 BMC with extra LAN communication support",
},
{
name: "intelplus",
desc: "Intel IPMI 2.0 BMC with RMCP+ communication support",
},
{
name: "icts",
desc: "IPMI 2.0 ICTS compliance support",
}, },
{ 0 }, { 0 },
}; };
@ -70,9 +78,7 @@ ipmi_oem_print(void)
{ {
struct ipmi_oem_handle * oem; struct ipmi_oem_handle * oem;
lprintf(LOG_NOTICE, "\nOEM Support:"); lprintf(LOG_NOTICE, "\nOEM Support:");
for (oem=ipmi_oem_list; oem->setup != NULL; oem++) { for (oem=ipmi_oem_list; oem->name != NULL && oem->desc != NULL; oem++) {
if (oem->name == NULL || oem->desc == NULL)
continue;
lprintf(LOG_NOTICE, "\t%-12s %s", oem->name, oem->desc); lprintf(LOG_NOTICE, "\t%-12s %s", oem->name, oem->desc);
} }
lprintf(LOG_NOTICE, ""); lprintf(LOG_NOTICE, "");
@ -90,6 +96,7 @@ int
ipmi_oem_setup(struct ipmi_intf * intf, char * oemtype) ipmi_oem_setup(struct ipmi_intf * intf, char * oemtype)
{ {
struct ipmi_oem_handle * oem; struct ipmi_oem_handle * oem;
int i;
int rc = 0; int rc = 0;
if (strncmp(oemtype, "help", 4) == 0 || if (strncmp(oemtype, "help", 4) == 0 ||
@ -99,7 +106,7 @@ ipmi_oem_setup(struct ipmi_intf * intf, char * oemtype)
return -1; return -1;
} }
for (oem=ipmi_oem_list; oem->setup != NULL; oem++) { for (oem=ipmi_oem_list, i=0; i < sizeof(ipmi_oem_list)/sizeof(struct ipmi_oem_handle); oem++, i++) {
if (oem->name == NULL) if (oem->name == NULL)
continue; continue;
if (strncmp(oemtype, oem->name, strlen(oem->name)) == 0) if (strncmp(oemtype, oem->name, strlen(oem->name)) == 0)

View File

@ -76,12 +76,6 @@ static const char * pef_flag_fmts[][3] = {
{"active", "in", ""}, {"active", "in", ""},
{"abled", "dis", "en"}, {"abled", "dis", "en"},
}; };
typedef enum {
P_TRUE,
P_SUPP,
P_ACTV,
P_ABLE,
} flg_e;
static const char * listitem[] = {" | %s", ",%s", "%s"}; static const char * listitem[] = {" | %s", ",%s", "%s"};
const char * const char *
@ -291,8 +285,8 @@ ipmi_pef_print_lan_dest(struct ipmi_intf * intf, uint8_t ch, uint8_t dest)
return; return;
} }
tbl_size = (rsp->data[1] & PEF_LAN_DEST_TABLE_SIZE_MASK); tbl_size = (rsp->data[1] & PEF_LAN_DEST_TABLE_SIZE_MASK);
if (!dest || tbl_size == 0) /* LAN alerting not supported */ //if (tbl_size == 0 || dest == 0) /* LAN alerting not supported */
return; // return;
lsel.id = PEF_LAN_CFGPARM_ID_DESTTYPE; lsel.id = PEF_LAN_CFGPARM_ID_DESTTYPE;
lsel.set = dest; lsel.set = dest;
@ -696,7 +690,7 @@ ipmi_pef_list_policies(struct ipmi_intf * intf)
if (ptmp->entry.alert_string_key & PEF_POLICY_EVENT_SPECIFIC) { if (ptmp->entry.alert_string_key & PEF_POLICY_EVENT_SPECIFIC) {
ipmi_pef_print_str("Event-specific", "true"); ipmi_pef_print_str("Event-specific", "true");
continue; // continue;
} }
wrk = ptmp->entry.chan_dest; wrk = ptmp->entry.chan_dest;
@ -777,6 +771,15 @@ ipmi_pef_get_status(struct ipmi_intf * intf)
return; return;
} }
ipmi_pef_print_flags(&pef_b2s_control, P_ABLE, rsp->data[1]); ipmi_pef_print_flags(&pef_b2s_control, P_ABLE, rsp->data[1]);
psel.id = PEF_CFGPARM_ID_PEF_ACTION;
rsp = ipmi_pef_msg_exchange(intf, &req, "PEF action");
if (!rsp) {
lprintf(LOG_ERR, " **Error retrieving %s",
"PEF action");
return;
}
ipmi_pef_print_flags(&pef_b2s_actions, P_ACTV, rsp->data[1]);
} }
static void static void

747
ipmitool/lib/ipmi_picmg.c Normal file
View File

@ -0,0 +1,747 @@
/*
(C) Kontron
*/
#include <ipmitool/ipmi_intf.h>
#include <ipmitool/ipmi_picmg.h>
#include <ipmitool/ipmi_fru.h> /* for access to link descriptor defines */
int
ipmi_picmg_help (void)
{
printf(" properties - get PICMG properties\n");
printf(" addrinfo - get address information\n");
printf(" activate - activate a FRU\n");
printf(" deactivate - deactivate a FRU\n");
printf(" policy get - get the FRU activation policy\n");
printf(" policy set - set the FRU activation policy\n");
printf(" portstate get - get port state \n");
printf(" portstate set - set port state \n");
printf(" led prop - get led properties\n");
printf(" led cap - get led color capabilities\n");
printf(" led state get - get led state\n");
printf(" led state set - set led state\n");
printf(" power get - get power level info\n");
printf(" power set - set power level\n");
}
int
ipmi_picmg_getaddr(struct ipmi_intf * intf)
{
struct ipmi_rs * rsp;
struct ipmi_rq req;
unsigned char msg_data;
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_PICMG;
req.msg.cmd = PICMG_GET_ADDRESS_INFO_CMD;
req.msg.data = &msg_data;
req.msg.data_len = 1;
msg_data = 0;
rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode) {
printf("Error getting address information\n");
return -1;
}
printf("Hardware Address : 0x%02x\n", rsp->data[1]);
printf("IPMB-0 Address : 0x%02x\n", rsp->data[2]);
printf("FRU ID : 0x%02x\n", rsp->data[4]);
printf("Site ID : 0x%02x\n", rsp->data[5]);
printf("Site Type : ");
switch (rsp->data[6]) {
case PICMG_ATCA_BOARD:
printf("ATCA board\n");
break;
case PICMG_POWER_ENTRY:
printf("Power Entry Module\n");
break;
case PICMG_SHELF_FRU:
printf("Shelf FRU\n");
break;
case PICMG_DEDICATED_SHMC:
printf("Dedicated Shelf Manager\n");
break;
case PICMG_FAN_TRAY:
printf("Fan Tray\n");
break;
case PICMG_FAN_FILTER_TRAY:
printf("Fan Filter Tray\n");
break;
case PICMG_ALARM:
printf("Alarm module\n");
break;
case PICMG_AMC:
printf("AMC\n");
break;
case PICMG_PMC:
printf("PMC\n");
break;
case PICMG_RTM:
printf("RTM\n");
break;
default:
if (rsp->data[6] >= 0xc0 && rsp->data[6] <= 0xcf) {
printf("OEM\n");
} else {
printf("unknown\n");
}
}
return 0;
}
int
ipmi_picmg_properties(struct ipmi_intf * intf)
{
struct ipmi_rs * rsp;
struct ipmi_rq req;
unsigned char msg_data;
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_PICMG;
req.msg.cmd = PICMG_GET_PICMG_PROPERTIES_CMD;
req.msg.data = &msg_data;
req.msg.data_len = 1;
msg_data = 0;
rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode) {
printf("Error getting address information\n");
return -1;
}
printf("PICMG identifier : 0x%02x\n", rsp->data[0]);
printf("PICMG Ext. Version : %i.%i\n", rsp->data[1]&0x0f, (rsp->data[1]&0xf0) >> 4);
printf("Max FRU Device ID : 0x%02x\n", rsp->data[2]);
printf("FRU Device ID : 0x%02x\n", rsp->data[3]);
}
#define PICMG_FRU_DEACTIVATE (unsigned char) 0x00
#define PICMG_FRU_ACTIVATE (unsigned char) 0x01
int
ipmi_picmg_fru_activation(struct ipmi_intf * intf, int argc, char ** argv, unsigned char state)
{
struct ipmi_rs * rsp;
struct ipmi_rq req;
struct picmg_set_fru_activation_cmd cmd;
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_PICMG;
req.msg.cmd = PICMG_FRU_ACTIVATION_CMD;
req.msg.data = (unsigned char*) &cmd;
req.msg.data_len = 3;
cmd.picmg_id = 0; /* PICMG identifier */
cmd.fru_id = (unsigned char) atoi(argv[0]); /* FRU ID */
cmd.fru_state = state;
rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode) {
printf("Error activation/deactivation of FRU\n");
return -1;
}
if (rsp->data[0] != 0x00) {
printf("Error\n");
}
return 0;
}
int
ipmi_picmg_fru_activation_policy_get(struct ipmi_intf * intf, int argc, char ** argv)
{
struct ipmi_rs * rsp;
struct ipmi_rq req;
unsigned char msg_data[4];
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_PICMG;
req.msg.cmd = PICMG_GET_FRU_POLICY_CMD;
req.msg.data = msg_data;
req.msg.data_len = 2;
msg_data[0] = 0; /* PICMG identifier */
msg_data[1] = (unsigned char) atoi(argv[0]); /* FRU ID */
rsp = intf->sendrecv(intf, &req);
if (!rsp) {
printf("no response\n");
return -1;
}
if (rsp->ccode) {
printf("returned CC code 0x%02x\n", rsp->ccode);
return -1;
}
printf("Activation Policy for FRU %x: ", atoi(argv[0]) );
printf(" %s\n",(*(rsp->data+3)&0x01 == 0x01)?"is locked":"is not locked");
return 0;
}
int
ipmi_picmg_portstate_get(struct ipmi_intf * intf, int argc, char ** argv)
{
struct ipmi_rs * rsp;
struct ipmi_rq req;
unsigned char msg_data[4];
struct fru_picmgext_link_desc* d; /* descriptor pointer for rec. data */
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_PICMG;
req.msg.cmd = PICMG_GET_PORT_STATE_CMD;
req.msg.data = msg_data;
req.msg.data_len = 2;
msg_data[0] = 0x00; /* PICMG identifier */
msg_data[1] = (atoi(argv[0]) & 0x3)<<6; /* interface */
msg_data[1] |= (atoi(argv[1]) & 0x3F); /* channel number */
rsp = intf->sendrecv(intf, &req);
if (!rsp) {
printf("no response\n");
return -1;
}
if (rsp->ccode) {
printf("returned CC code 0x%02x\n", rsp->ccode);
return -1;
}
if (rsp->data_len == 6) {
d = (struct fru_picmgext_link_desc *) &(rsp->data[1]);
printf(" Link Grouping ID: 0x%02x\n", d->grouping);
printf(" Link Type Extension: 0x%02x\n", d->ext);
printf(" Link Type: ");
if (d->type == 0 || d->type == 0xff)
{
printf("Reserved\n");
}
else if (d->type >= 0x06 && d->type <= 0xef)
{
printf("Reserved\n");
}
else if (d->type >= 0xf0 && d->type <= 0xfe)
{
printf("OEM GUID Definition\n");
}
else
{
switch (d->type)
{
case FRU_PICMGEXT_LINK_TYPE_BASE:
printf("PICMG 3.0 Base Interface 10/100/1000\n");
break;
case FRU_PICMGEXT_LINK_TYPE_FABRIC_ETHERNET:
printf("PICMG 3.1 Ethernet Fabric Interface\n");
break;
case FRU_PICMGEXT_LINK_TYPE_FABRIC_INFINIBAND:
printf("PICMG 3.2 Infiniband Fabric Interface\n");
break;
case FRU_PICMGEXT_LINK_TYPE_FABRIC_STAR:
printf("PICMG 3.3 Star Fabric Interface\n");
break;
case FRU_PICMGEXT_LINK_TYPE_PCIE:
printf("PCI Express Fabric Interface\n");
default:
printf("Invalid\n");
}
}
printf(" Link Designator: 0x%03x\n", d->designator);
printf(" Port Flag: 0x%02x\n", d->designator >> 8);
printf(" Interface: ");
switch ((d->designator & 0xff) >> 6)
{
case FRU_PICMGEXT_DESIGN_IF_BASE:
printf("Base Interface\n");
break;
case FRU_PICMGEXT_DESIGN_IF_FABRIC:
printf("Fabric Interface\n");
break;
case FRU_PICMGEXT_DESIGN_IF_UPDATE_CHANNEL:
printf("Update Channel\n");
break;
case FRU_PICMGEXT_DESIGN_IF_RESERVED:
printf("Reserved\n");
default:
printf("Invalid");
}
printf(" Channel Number: 0x%02x\n", d->designator & 0x1f);
printf("\n");
printf(" STATE: %s\n", rsp->data[5] == 0x01?"enabled":"disabled");
}
return 0;
}
int
ipmi_picmg_portstate_set(struct ipmi_intf * intf, int argc, char ** argv)
{
struct ipmi_rs * rsp;
struct ipmi_rq req;
unsigned char msg_data[6];
struct fru_picmgext_link_desc* d;
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_PICMG;
req.msg.cmd = PICMG_SET_PORT_STATE_CMD;
req.msg.data = msg_data;
req.msg.data_len = 6;
msg_data[0] = 0x00; /* PICMG identifier */
d = (struct fru_picmgext_link_desc*) &(msg_data[1]);
d->designator = (unsigned char) (atoi(argv[0]) & 0x1F); /* channel */
d->designator = (unsigned char) ((atoi(argv[1]) & 0x03) << 6); /* interface */
d->designator = (unsigned char) ((atoi(argv[2]) & 0x03) << 8); /* port */
d->type = (unsigned char) (atoi(argv[3]) & 0xFF); /* link type */
d->ext = (unsigned char) (atoi(argv[4]) & 0x03); /* type ext */
d->grouping = (unsigned char) (atoi(argv[5]) & 0xFF); /* type ext */
msg_data[5] = (unsigned char) (atoi(argv[6]) & 0x01); /* en/dis */
rsp = intf->sendrecv(intf, &req);
if (!rsp) {
printf("no response\n");
return -1;
}
if (rsp->ccode) {
printf("returned CC code 0x%02x\n", rsp->ccode);
return -1;
}
return 0;
}
int
ipmi_picmg_get_led_properties(struct ipmi_intf * intf, int argc, char ** argv)
{
struct ipmi_rs * rsp;
struct ipmi_rq req;
unsigned char msg_data[6];
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_PICMG;
req.msg.cmd = PICMG_GET_FRU_LED_PROPERTIES_CMD;
req.msg.data = msg_data;
req.msg.data_len = 2;
msg_data[0] = 0x00; /* PICMG identifier */
msg_data[1] = atoi(argv[0]); /* FRU-ID */
rsp = intf->sendrecv(intf, &req);
if (!rsp) {
printf("no response\n");
return -1;
}
if (rsp->ccode) {
printf("returned CC code 0x%02x\n", rsp->ccode);
return -1;
}
printf("General Status LED Properties: 0x%2x\n\r", rsp->data[1] );
printf("App. Specific LED Count: 0x%2x\n\r", rsp->data[2] );
return 0;
}
int
ipmi_picmg_get_led_capabilities(struct ipmi_intf * intf, int argc, char ** argv)
{
int i;
struct ipmi_rs * rsp;
struct ipmi_rq req;
unsigned char msg_data[6];
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_PICMG;
req.msg.cmd = PICMG_GET_LED_COLOR_CAPABILITIES_CMD;
req.msg.data = msg_data;
req.msg.data_len = 3;
msg_data[0] = 0x00; /* PICMG identifier */
msg_data[1] = atoi(argv[0]); /* FRU-ID */
msg_data[2] = atoi(argv[1]); /* LED-ID */
rsp = intf->sendrecv(intf, &req);
if (!rsp) {
printf("no response\n");
return -1;
}
if (rsp->ccode) {
printf("returned CC code 0x%02x\n", rsp->ccode);
return -1;
}
printf("LED Color Capabilities: ", rsp->data[1] );
for ( i=0 ; i<8 ; i++ ) {
if ( rsp->data[1] & (0x01 << i) ) {
printf("%s, ", led_color_str[ i ]);
}
}
printf("\n\r");
printf("Default LED Color in\n\r");
printf(" LOCAL control: %s\n\r", led_color_str[ rsp->data[2] ] );
printf(" OVERRIDE state: %s\n\r", led_color_str[ rsp->data[3] ] );
return 0;
}
int
ipmi_picmg_get_led_state(struct ipmi_intf * intf, int argc, char ** argv)
{
int i;
struct ipmi_rs * rsp;
struct ipmi_rq req;
unsigned char msg_data[6];
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_PICMG;
req.msg.cmd = PICMG_GET_FRU_LED_STATE_CMD;
req.msg.data = msg_data;
req.msg.data_len = 3;
msg_data[0] = 0x00; /* PICMG identifier */
msg_data[1] = atoi(argv[0]); /* FRU-ID */
msg_data[2] = atoi(argv[1]); /* LED-ID */
rsp = intf->sendrecv(intf, &req);
if (!rsp) {
printf("no response\n");
return -1;
}
if (rsp->ccode) {
printf("returned CC code 0x%02x\n", rsp->ccode);
return -1;
}
printf("LED states: %x\n\r", rsp->data[1] );
printf(" Local Control function: %x\n\r", rsp->data[2] );
printf(" Local Control On-Duration: %x\n\r", rsp->data[3] );
printf(" Local Control Color: %s\n\r", led_color_str[ rsp->data[4] ]);
/* override state or lamp test */
if (rsp->data[1] == 0x01) {
printf(" Override function: %x\n\r", rsp->data[5] );
printf(" Override On-Duration: %x\n\r", rsp->data[6] );
printf(" Override Color: %s\n\r", led_color_str[ rsp->data[7] ]);
}else if (rsp->data[1] == 0x03) {
printf(" Override function: %x\n\r", rsp->data[5] );
printf(" Override On-Duration: %x\n\r", rsp->data[6] );
printf(" Override Color: %s\n\r", led_color_str[ rsp->data[7] ]);
printf(" Lamp test duration: %x\n\r", rsp->data[8] );
}
return 0;
}
int
ipmi_picmg_set_led_state(struct ipmi_intf * intf, int argc, char ** argv)
{
int i;
struct ipmi_rs * rsp;
struct ipmi_rq req;
unsigned char msg_data[6];
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_PICMG;
req.msg.cmd = PICMG_SET_FRU_LED_STATE_CMD;
req.msg.data = msg_data;
req.msg.data_len = 6;
msg_data[0] = 0x00; /* PICMG identifier */
msg_data[1] = atoi(argv[0]); /* FRU-ID */
msg_data[2] = atoi(argv[1]); /* LED-ID */
msg_data[3] = atoi(argv[2]); /* LED function */
msg_data[4] = atoi(argv[3]); /* LED on duration */
msg_data[5] = atoi(argv[4]); /* LED color */
rsp = intf->sendrecv(intf, &req);
if (!rsp) {
printf("no response\n");
return -1;
}
if (rsp->ccode) {
printf("returned CC code 0x%02x\n", rsp->ccode);
return -1;
}
return 0;
}
int
ipmi_picmg_get_power_level(struct ipmi_intf * intf, int argc, char ** argv)
{
int i;
struct ipmi_rs * rsp;
struct ipmi_rq req;
unsigned char msg_data[6];
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_PICMG;
req.msg.cmd = PICMG_GET_POWER_LEVEL_CMD;
req.msg.data = msg_data;
req.msg.data_len = 3;
msg_data[0] = 0x00; /* PICMG identifier */
msg_data[1] = atoi(argv[0]); /* FRU-ID */
msg_data[2] = atoi(argv[1]); /* Power type */
rsp = intf->sendrecv(intf, &req);
if (!rsp) {
printf("no response\n");
return -1;
}
if (rsp->ccode) {
printf("returned CC code 0x%02x\n", rsp->ccode);
return -1;
}
printf("Dynamic Power Configuration: %s\n", (rsp->data[1]&0x80)==0x80?"enabled":"disabled" );
printf("Actual Power Level: %i\n", (rsp->data[1] & 0xf));
printf("Delay to stable Power: %i\n", rsp->data[2]);
printf("Power Multiplier: %i\n", rsp->data[3]);
for ( i = 1; i+3 < rsp->data_len ; i++ ) {
printf(" Power Draw %i: %i\n", i, rsp->data[i+3]);
}
return 0;
}
int
ipmi_picmg_main (struct ipmi_intf * intf, int argc, char ** argv)
{
int rc;
if (argc == 0 || (!strncmp(argv[0], "help", 4))) {
ipmi_picmg_help();
return 0;
}
/* address info command */
else if (!strncmp(argv[0], "addrinfo", 8)) {
rc = ipmi_picmg_getaddr(intf);
}
/* picmg properties command */
else if (!strncmp(argv[0], "properties", 10)) {
rc = ipmi_picmg_properties(intf);
}
/* fru activation command */
else if (!strncmp(argv[0], "activate", 8)) {
if (argc > 1) {
rc = ipmi_picmg_fru_activation(intf, argc-1, &(argv[1]), PICMG_FRU_ACTIVATE);
}
else {
printf("specify the FRU to activate\n");
return -1;
}
}
/* fru deactivation command */
else if (!strncmp(argv[0], "deactivate", 10)) {
if (argc > 1) {
rc = ipmi_picmg_fru_activation(intf, argc-1, &(argv[1]), PICMG_FRU_DEACTIVATE);
}else {
printf("specify the FRU to deactivate\n");
return -1;
}
}
/* activation policy command */
else if (!strncmp(argv[0], "policy", 6)) {
if (argc > 2) {
if (!strncmp(argv[1], "get", 3)) {
rc = ipmi_picmg_fru_activation_policy_get(intf, argc-1, &(argv[2]));
}
else if (!strncmp(argv[1], "set", 6)) {
printf("tbd\n");
return -1;
}
else {
printf("specify fru\n");
return -1;
}
}else {
printf("wrong parameters\n");
return -1;
}
}
/* portstate command */
else if (!strncmp(argv[0], "portstate", 9)) {
if (argc > 2) {
if (!strncmp(argv[1], "get", 3)) {
rc = ipmi_picmg_portstate_get(intf, argc-1, &(argv[2]));
}
else {
printf("portstate get <intf><chn>\n");
}
}
else if (!strncmp(argv[1], "set", 3)) {
if (argc > 5) {
rc = ipmi_picmg_portstate_set(intf, argc-1, &(argv[2]));
}
else {
printf("portstate set <chn><intf><port><type><typeext><group><en|dis>\n");
return -1;
}
}
else {
printf("<set>|<get>\n");
return -1;
}
}
/* ATCA led commands */
else if (!strncmp(argv[0], "led", 3)) {
if (argc > 1) {
if (!strncmp(argv[1], "prop", 4)) {
if (argc > 2) {
rc = ipmi_picmg_get_led_properties(intf, argc-1, &(argv[2]));
}
else {
printf("led prop <FRU-ID>\n");
}
}
else if (!strncmp(argv[1], "cap", 3)) {
if (argc > 3) {
rc = ipmi_picmg_get_led_capabilities(intf, argc-1, &(argv[2]));
}
else {
printf("led cap <FRU-ID> <LED-ID>\n");
}
}
else if (!strncmp(argv[1], "get", 3)) {
if (argc > 3) {
rc = ipmi_picmg_get_led_state(intf, argc-1, &(argv[2]));
}
else {
printf("led get <FRU-ID> <LED-ID>\n");
}
}
else if (!strncmp(argv[1], "set", 3)) {
if (argc > 6) {
rc = ipmi_picmg_set_led_state(intf, argc-1, &(argv[2]));
}
else {
printf("led set <FRU-ID> <LED-ID> <function> <duration> <color>\n");
printf(" <FRU-ID>\n");
printf(" <LED-ID>\n");
printf(" <function> 0: LED OFF override\n");
printf(" 1 - 250: LED blinking override (off duration)\n");
printf(" 251: LED Lamp Test\n");
printf(" 252: LED restore to local control\n");
printf(" 255: LED ON override\n");
printf(" <duration> 1 - 127: LED Lamp Test / on duration\n");
printf(" <color> \n");
}
}
else {
printf("prop | cap | get | set\n");
}
}
}
/* power commands */
else if (!strncmp(argv[0], "power", 5)) {
if (argc > 1) {
if (!strncmp(argv[1], "get", 3)) {
if (argc > 3) {
rc = ipmi_picmg_get_power_level(intf, argc-1, &(argv[2]));
}
else {
printf("power get <FRI-ID> <type>\n");
printf(" <type> 0 : steady state powert draw levels\n");
printf(" 1 : desired steady state draw levels\n");
printf(" 2 : early power draw levels\n");
printf(" 3 : desired early levels\n");
return -1;
}
}
else if (!strncmp(argv[1], "set", 3)) {
if (argc > 5) {
printf("not implemented yet\n");
}
else {
return -1;
}
}
else {
printf("<set>|<get>\n");
return -1;
}
}
else {
printf("<set>|<get>\n");
return -1;
}
}
else {
ipmi_picmg_help();
return -1;
}
return rc;
}

View File

@ -43,27 +43,213 @@
#include <ipmitool/helper.h> #include <ipmitool/helper.h>
#include <ipmitool/ipmi_intf.h> #include <ipmitool/ipmi_intf.h>
#include <ipmitool/ipmi_raw.h> #include <ipmitool/ipmi_raw.h>
#include <ipmitool/ipmi_strings.h>
#define IPMI_I2C_MASTER_MAX_SIZE 0x40
/* ipmi_master_write_read - Perform I2C write/read transactions
*
* This function performs an I2C master write-read function through
* IPMI interface. It has a maximum transfer size of 32 bytes.
*
* @intf: ipmi interface
* @addr: i2c slave address
* @wdata: data to write
* @wsize: length of data to write (max 64 bytes)
* @rsize: length of data to read (max 64 bytes)
*
* Returns pointer to IPMI Response
*/
struct ipmi_rs *
ipmi_master_write_read(struct ipmi_intf * intf, uint8_t addr, uint8_t * wdata, uint8_t wsize, uint8_t rsize)
{
struct ipmi_rq req;
struct ipmi_rs * rsp;
uint8_t rqdata[IPMI_I2C_MASTER_MAX_SIZE + 3];
if (rsize > IPMI_I2C_MASTER_MAX_SIZE) {
lprintf(LOG_ERR, "Master Write-Read: Too many bytes (%d) to read", rsize);
return NULL;
}
if (wsize > IPMI_I2C_MASTER_MAX_SIZE) {
lprintf(LOG_ERR, "Master Write-Read: Too many bytes (%d) to write", wsize);
return NULL;
}
memset(&req, 0, sizeof(struct ipmi_rq));
req.msg.netfn = IPMI_NETFN_APP;
req.msg.cmd = 0x52; /* master write-read */
req.msg.data = rqdata;
req.msg.data_len = 3;
memset(rqdata, 0, IPMI_I2C_MASTER_MAX_SIZE + 3);
rqdata[0] = 0x00; /* channel number, bus id, bus type */
rqdata[1] = addr; /* slave address */
rqdata[2] = rsize; /* number of bytes to read */
if (wsize > 0) {
/* copy in data to write */
memcpy(rqdata+3, wdata, wsize);
req.msg.data_len += wsize;
lprintf(LOG_DEBUG, "Writing %d bytes to i2cdev %02Xh", wsize, addr);
}
if (rsize > 0) {
lprintf(LOG_DEBUG, "Reading %d bytes from i2cdev %02Xh", rsize, addr);
}
rsp = intf->sendrecv(intf, &req);
if (rsp == NULL) {
lprintf(LOG_ERR, "I2C Master Write-Read command failed");
return NULL;
}
else if (rsp->ccode > 0) {
switch (rsp->ccode) {
case 0x81:
lprintf(LOG_ERR, "I2C Master Write-Read command failed: Lost Arbitration");
break;
case 0x82:
lprintf(LOG_ERR, "I2C Master Write-Read command failed: Bus Error");
break;
case 0x83:
lprintf(LOG_ERR, "I2C Master Write-Read command failed: NAK on Write");
break;
case 0x84:
lprintf(LOG_ERR, "I2C Master Write-Read command failed: Truncated Read");
break;
default:
lprintf(LOG_ERR, "I2C Master Write-Read command failed: %s",
val2str(rsp->ccode, completion_code_vals));
break;
}
return NULL;
}
return rsp;
}
static void rawi2c_usage(void)
{
lprintf(LOG_NOTICE, "usage: i2c <i2caddr> <read bytes> [write data]");
}
int
ipmi_rawi2c_main(struct ipmi_intf * intf, int argc, char ** argv)
{
struct ipmi_rs * rsp;
uint8_t wdata[IPMI_I2C_MASTER_MAX_SIZE];
uint8_t i2caddr = 0;
uint8_t rsize = 0;
uint8_t wsize = 0;
int i;
if (argc < 2 || strncmp(argv[0], "help", 4) == 0) {
rawi2c_usage();
return 0;
}
else if (argc-2 > IPMI_I2C_MASTER_MAX_SIZE) {
lprintf(LOG_ERR, "Raw command input limit (%d bytes) exceeded",
IPMI_I2C_MASTER_MAX_SIZE);
return -1;
}
i2caddr = (uint8_t)strtoul(argv[0], NULL, 0);
rsize = (uint8_t)strtoul(argv[1], NULL, 0);
if (i2caddr == 0) {
lprintf(LOG_ERR, "Invalid I2C address 0");
rawi2c_usage();
return -1;
}
memset(wdata, 0, IPMI_I2C_MASTER_MAX_SIZE);
for (i=2; i<argc; i++) {
uint8_t val = (uint8_t)strtol(argv[i], NULL, 0);
wdata[i-2] = val;
wsize++;
}
lprintf(LOG_INFO, "RAW I2C REQ (i2caddr=%x readbytes=%d writebytes=%d)",
i2caddr, rsize, wsize);
printbuf(wdata, wsize, "WRITE DATA");
rsp = ipmi_master_write_read(intf, i2caddr, wdata, wsize, rsize);
if (rsp == NULL) {
lprintf(LOG_ERR, "Unable to perform I2C Master Write-Read");
return -1;
}
if (wsize > 0) {
if (verbose || rsize == 0)
printf("Wrote %d bytes to I2C device %02Xh\n", wsize, i2caddr);
}
if (rsize > 0) {
if (verbose || wsize == 0)
printf("Read %d bytes from I2C device %02Xh\n", rsp->data_len, i2caddr);
/* print the raw response buffer */
for (i=0; i<rsp->data_len; i++) {
if (((i%16) == 0) && (i != 0))
printf("\n");
printf(" %2.2x", rsp->data[i]);
}
printf("\n");
if (rsp->data_len <= 4) {
uint32_t bit;
int j;
for (i = 0; i < rsp->data_len; i++) {
for (j = 1, bit = 0x80; bit > 0; bit /= 2, j++) {
printf("%s", (rsp->data[i] & bit) ? "1" : "0");
}
printf(" ");
}
printf("\n");
}
}
return 0;
}
int int
ipmi_raw_main(struct ipmi_intf * intf, int argc, char ** argv) ipmi_raw_main(struct ipmi_intf * intf, int argc, char ** argv)
{ {
struct ipmi_rs * rsp; struct ipmi_rs * rsp;
struct ipmi_rq req; struct ipmi_rq req;
uint8_t netfn, cmd; uint8_t netfn, cmd, lun;
int i; int i;
uint8_t data[32]; unsigned long ufn;
uint8_t data[256];
if (argc < 2 || strncmp(argv[0], "help", 4) == 0) { if (argc < 2 || strncmp(argv[0], "help", 4) == 0) {
lprintf(LOG_NOTICE, "RAW Commands: raw <netfn> <cmd> [data]"); lprintf(LOG_NOTICE, "RAW Commands: raw <netfn> <cmd> [data]");
print_valstr(ipmi_netfn_vals, "Network Function Codes", LOG_NOTICE);
lprintf(LOG_NOTICE, "(can also use raw hex values)");
return -1;
}
else if (argc > sizeof(data))
{
lprintf(LOG_NOTICE, "Raw command input limit (256 bytes) exceeded");
return -1; return -1;
} }
ipmi_intf_session_set_timeout(intf, 15);
ipmi_intf_session_set_retry(intf, 1);
lun = intf->target_lun;
netfn = str2val(argv[0], ipmi_netfn_vals);
if (netfn == 0xff) {
netfn = (uint8_t)strtol(argv[0], NULL, 0); netfn = (uint8_t)strtol(argv[0], NULL, 0);
}
cmd = (uint8_t)strtol(argv[1], NULL, 0); cmd = (uint8_t)strtol(argv[1], NULL, 0);
memset(data, 0, sizeof(data)); memset(data, 0, sizeof(data));
memset(&req, 0, sizeof(req)); memset(&req, 0, sizeof(req));
req.msg.netfn = netfn; req.msg.netfn = netfn;
req.msg.lun = lun;
req.msg.cmd = cmd; req.msg.cmd = cmd;
req.msg.data = data; req.msg.data = data;
@ -73,8 +259,10 @@ ipmi_raw_main(struct ipmi_intf * intf, int argc, char ** argv)
req.msg.data_len++; req.msg.data_len++;
} }
lprintf(LOG_INFO, "RAW REQ (netfn=0x%x cmd=0x%x data_len=%d)", lprintf(LOG_INFO,
req.msg.netfn, req.msg.cmd, req.msg.data_len); "RAW REQ (channel=0x%x netfn=0x%x lun=0x%x cmd=0x%x data_len=%d)",
intf->target_channel & 0x0f, req.msg.netfn,req.msg.lun ,
req.msg.cmd, req.msg.data_len);
printbuf(req.msg.data, req.msg.data_len, "RAW REQUEST"); printbuf(req.msg.data, req.msg.data_len, "RAW REQUEST");
@ -82,14 +270,14 @@ ipmi_raw_main(struct ipmi_intf * intf, int argc, char ** argv)
if (rsp == NULL) { if (rsp == NULL) {
lprintf(LOG_ERR, "Unable to send RAW command " lprintf(LOG_ERR, "Unable to send RAW command "
"(netfn=0x%x cmd=0x%x)", "(channel=0x%x netfn=0x%x lun=0x%x cmd=0x%x)",
req.msg.netfn, req.msg.cmd); intf->target_channel & 0x0f, req.msg.netfn, req.msg.lun, req.msg.cmd);
return -1; return -1;
} }
if (rsp->ccode > 0) { if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Unable to send RAW command " lprintf(LOG_ERR, "Unable to send RAW command "
"(netfn=0x%x cmd=0x%x): %s", "(channel=0x%x netfn=0x%x lun=0x%x cmd=0x%x rsp=0x%x): %s",
req.msg.netfn, req.msg.cmd, intf->target_channel & 0x0f, req.msg.netfn, req.msg.lun, req.msg.cmd, rsp->ccode,
val2str(rsp->ccode, completion_code_vals)); val2str(rsp->ccode, completion_code_vals));
return -1; return -1;
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -49,27 +49,11 @@ extern int verbose;
#define READING_UNAVAILABLE 0x20 #define READING_UNAVAILABLE 0x20
static
struct ipmi_rs *
ipmi_sensor_get_sensor_thresholds(struct ipmi_intf * intf, uint8_t sensor)
{
struct ipmi_rq req;
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_SE;
req.msg.cmd = GET_SENSOR_THRESHOLDS;
req.msg.data = &sensor;
req.msg.data_len = sizeof(sensor);
return intf->sendrecv(intf, &req);
}
static static
struct ipmi_rs * struct ipmi_rs *
ipmi_sensor_set_sensor_thresholds(struct ipmi_intf *intf, ipmi_sensor_set_sensor_thresholds(struct ipmi_intf *intf,
uint8_t sensor, uint8_t sensor,
uint8_t threshold, uint8_t threshold, uint8_t setting)
uint8_t setting)
{ {
struct ipmi_rq req; struct ipmi_rq req;
static struct sensor_set_thresh_rq set_thresh_rq; static struct sensor_set_thresh_rq set_thresh_rq;
@ -120,7 +104,9 @@ ipmi_sensor_print_full_discrete(struct ipmi_intf * intf,
/* /*
* Get current reading * Get current reading
*/ */
rsp = ipmi_sdr_get_sensor_reading(intf, sensor->keys.sensor_num); rsp = ipmi_sdr_get_sensor_reading_ipmb(intf,
sensor->keys.sensor_num,
sensor->keys.owner_id);
if (rsp == NULL) { if (rsp == NULL) {
lprintf(LOG_ERR, "Error reading sensor %s (#%02x)", lprintf(LOG_ERR, "Error reading sensor %s (#%02x)",
id, sensor->keys.sensor_num); id, sensor->keys.sensor_num);
@ -132,12 +118,9 @@ ipmi_sensor_print_full_discrete(struct ipmi_intf * intf,
val = rsp->data[0]; val = rsp->data[0];
} }
if (csv_output) if (csv_output) {
{
/* NOT IMPLEMENTED */ /* NOT IMPLEMENTED */
} } else {
else
{
if (verbose == 0) { if (verbose == 0) {
/* output format /* output format
* id value units status thresholds.... * id value units status thresholds....
@ -146,14 +129,10 @@ ipmi_sensor_print_full_discrete(struct ipmi_intf * intf,
if (validread) { if (validread) {
printf("| 0x%-8x | %-10s | 0x%02x%02x", printf("| 0x%-8x | %-10s | 0x%02x%02x",
val, val,
unitstr, unitstr, rsp->data[2], rsp->data[3]);
rsp->data[2],
rsp->data[3]);
} else { } else {
printf("| %-10s | %-10s | %-6s", printf("| %-10s | %-10s | %-6s",
"na", "na", unitstr, "na");
unitstr,
"na");
} }
printf("| %-10s| %-10s| %-10s| %-10s| %-10s| %-10s", printf("| %-10s| %-10s| %-10s| %-10s| %-10s| %-10s",
"na", "na", "na", "na", "na", "na"); "na", "na", "na", "na", "na", "na");
@ -165,10 +144,13 @@ ipmi_sensor_print_full_discrete(struct ipmi_intf * intf,
printf(" Entity ID : %d.%d\n", printf(" Entity ID : %d.%d\n",
sensor->entity.id, sensor->entity.instance); sensor->entity.id, sensor->entity.instance);
printf(" Sensor Type (Discrete): %s\n", printf(" Sensor Type (Discrete): %s\n",
ipmi_sdr_get_sensor_type_desc(sensor->sensor.type)); ipmi_sdr_get_sensor_type_desc(sensor->sensor.
ipmi_sdr_print_discrete_state(sensor->sensor.type, type));
ipmi_sdr_print_discrete_state("States Asserted",
sensor->sensor.type,
sensor->event_type, sensor->event_type,
rsp->data[2]); rsp->data[2],
rsp->data[3]);
printf("\n"); printf("\n");
} }
} }
@ -182,27 +164,28 @@ ipmi_sensor_print_full_analog(struct ipmi_intf * intf,
{ {
char unitstr[16], id[17]; char unitstr[16], id[17];
int i = 0, validread = 1, thresh_available = 1; int i = 0, validread = 1, thresh_available = 1;
float val = 0.0; double val = 0.0;
struct ipmi_rs *rsp; struct ipmi_rs *rsp;
char *status = NULL; char *status = NULL;
if (sensor == NULL) if (sensor == NULL)
return -1; return -1;
/* only handle linear sensors (for now) */
if (sensor->linearization) {
lprintf(LOG_ERR, "Sensor #%02x is non-linear",
sensor->keys.sensor_num);
return -1;
}
memset(id, 0, sizeof (id)); memset(id, 0, sizeof (id));
memcpy(id, sensor->id_string, 16); memcpy(id, sensor->id_string, 16);
/* only handle linear and linearized sensors (for now) */
if (sensor->linearization >= SDR_SENSOR_L_NONLINEAR) {
printf("sensor %s non-linear!\n", id);
return -1;
}
/* /*
* Get current reading * Get current reading
*/ */
rsp = ipmi_sdr_get_sensor_reading(intf, sensor->keys.sensor_num); rsp = ipmi_sdr_get_sensor_reading_ipmb(intf,
sensor->keys.sensor_num,
sensor->keys.owner_id);
if (rsp == NULL) { if (rsp == NULL) {
lprintf(LOG_ERR, "Error reading sensor %s (#%02x)", lprintf(LOG_ERR, "Error reading sensor %s (#%02x)",
id, sensor->keys.sensor_num); id, sensor->keys.sensor_num);
@ -214,15 +197,14 @@ ipmi_sensor_print_full_analog(struct ipmi_intf * intf,
val = (rsp->data[0] > 0) val = (rsp->data[0] > 0)
? sdr_convert_sensor_reading(sensor, rsp->data[0]) ? sdr_convert_sensor_reading(sensor, rsp->data[0])
: 0; : 0;
status = (char*)ipmi_sdr_get_status(rsp->data[2]); status = (char *) ipmi_sdr_get_status(sensor, rsp->data[2]);
} }
/* /*
* Figure out units * Figure out units
*/ */
memset(unitstr, 0, sizeof (unitstr)); memset(unitstr, 0, sizeof (unitstr));
switch (sensor->unit.modifier) switch (sensor->unit.modifier) {
{
case 2: case 2:
i += snprintf(unitstr, sizeof (unitstr), "%s * %s", i += snprintf(unitstr, sizeof (unitstr), "%s * %s",
unit_desc[sensor->unit.type.base], unit_desc[sensor->unit.type.base],
@ -243,18 +225,14 @@ ipmi_sensor_print_full_analog(struct ipmi_intf * intf,
/* /*
* Get sensor thresholds * Get sensor thresholds
*/ */
rsp = ipmi_sensor_get_sensor_thresholds(intf, sensor->keys.sensor_num); rsp = ipmi_sdr_get_sensor_thresholds(intf, sensor->keys.sensor_num);
if (rsp == NULL) if (rsp == NULL)
thresh_available = 0; thresh_available = 0;
if (csv_output) if (csv_output) {
{
/* NOT IPMLEMENTED */ /* NOT IPMLEMENTED */
} } else {
else if (verbose == 0) {
{
if (verbose == 0)
{
/* output format /* output format
* id value units status thresholds.... * id value units status thresholds....
*/ */
@ -266,43 +244,51 @@ ipmi_sensor_print_full_analog(struct ipmi_intf * intf,
printf("| %-10s | %-10s | %-6s", printf("| %-10s | %-10s | %-6s",
"na", unitstr, "na"); "na", unitstr, "na");
} }
if (thresh_available) if (thresh_available) {
{
if (rsp->data[0] & LOWER_NON_RECOV_SPECIFIED) if (rsp->data[0] & LOWER_NON_RECOV_SPECIFIED)
printf("| %-10.3f", sdr_convert_sensor_reading(sensor, rsp->data[3])); printf("| %-10.3f",
sdr_convert_sensor_reading
(sensor, rsp->data[3]));
else else
printf("| %-10s", "na"); printf("| %-10s", "na");
if (rsp->data[0] & LOWER_CRIT_SPECIFIED) if (rsp->data[0] & LOWER_CRIT_SPECIFIED)
printf("| %-10.3f", sdr_convert_sensor_reading(sensor, rsp->data[2])); printf("| %-10.3f",
sdr_convert_sensor_reading
(sensor, rsp->data[2]));
else else
printf("| %-10s", "na"); printf("| %-10s", "na");
if (rsp->data[0] & LOWER_NON_CRIT_SPECIFIED) if (rsp->data[0] & LOWER_NON_CRIT_SPECIFIED)
printf("| %-10.3f", sdr_convert_sensor_reading(sensor, rsp->data[1])); printf("| %-10.3f",
sdr_convert_sensor_reading
(sensor, rsp->data[1]));
else else
printf("| %-10s", "na"); printf("| %-10s", "na");
if (rsp->data[0] & UPPER_NON_CRIT_SPECIFIED) if (rsp->data[0] & UPPER_NON_CRIT_SPECIFIED)
printf("| %-10.3f", sdr_convert_sensor_reading(sensor, rsp->data[4])); printf("| %-10.3f",
sdr_convert_sensor_reading
(sensor, rsp->data[4]));
else else
printf("| %-10s", "na"); printf("| %-10s", "na");
if (rsp->data[0] & UPPER_CRIT_SPECIFIED) if (rsp->data[0] & UPPER_CRIT_SPECIFIED)
printf("| %-10.3f", sdr_convert_sensor_reading(sensor, rsp->data[5])); printf("| %-10.3f",
sdr_convert_sensor_reading
(sensor, rsp->data[5]));
else else
printf("| %-10s", "na"); printf("| %-10s", "na");
if (rsp->data[0] & UPPER_NON_RECOV_SPECIFIED) if (rsp->data[0] & UPPER_NON_RECOV_SPECIFIED)
printf("| %-10.3f", sdr_convert_sensor_reading(sensor, rsp->data[6])); printf("| %-10.3f",
sdr_convert_sensor_reading
(sensor, rsp->data[6]));
else else
printf("| %-10s", "na"); printf("| %-10s", "na");
} } else {
else printf
{ ("| %-10s| %-10s| %-10s| %-10s| %-10s| %-10s",
printf("| %-10s| %-10s| %-10s| %-10s| %-10s| %-10s",
"na", "na", "na", "na", "na", "na"); "na", "na", "na", "na", "na", "na");
} }
printf("\n"); printf("\n");
} } else {
else
{
printf("Sensor ID : %s (0x%x)\n", printf("Sensor ID : %s (0x%x)\n",
id, sensor->keys.sensor_num); id, sensor->keys.sensor_num);
@ -310,61 +296,98 @@ ipmi_sensor_print_full_analog(struct ipmi_intf * intf,
sensor->entity.id, sensor->entity.instance); sensor->entity.id, sensor->entity.instance);
printf(" Sensor Type (Analog) : %s\n", printf(" Sensor Type (Analog) : %s\n",
ipmi_sdr_get_sensor_type_desc(sensor->sensor.type)); ipmi_sdr_get_sensor_type_desc(sensor->sensor.
type));
printf(" Sensor Reading : "); printf(" Sensor Reading : ");
if (validread) { if (validread) {
uint16_t raw_tol = __TO_TOL(sensor->mtol); uint16_t raw_tol = __TO_TOL(sensor->mtol);
float tol = sdr_convert_sensor_reading(sensor, raw_tol * 2); double tol =
sdr_convert_sensor_reading(sensor,
raw_tol * 2);
printf("%.*f (+/- %.*f) %s\n", printf("%.*f (+/- %.*f) %s\n",
(val==(int)val) ? 0 : 3, (val == (int) val) ? 0 : 3, val,
val, (tol == (int) tol) ? 0 : 3, tol,
(tol==(int)tol) ? 0 : 3,
tol,
unitstr); unitstr);
printf(" Status : %s\n", status ? : ""); printf(" Status : %s\n",
status ? : "");
if (thresh_available) if (thresh_available) {
{ if (rsp->
if (rsp->data[0] & LOWER_NON_RECOV_SPECIFIED) data[0] & LOWER_NON_RECOV_SPECIFIED)
printf(" Lower Non-Recoverable : %.3f\n", printf
sdr_convert_sensor_reading(sensor, rsp->data[3])); (" Lower Non-Recoverable : %.3f\n",
sdr_convert_sensor_reading
(sensor, rsp->data[3]));
else else
printf(" Lower Non-Recoverable : na\n"); printf
(" Lower Non-Recoverable : na\n");
if (rsp->data[0] & LOWER_CRIT_SPECIFIED) if (rsp->data[0] & LOWER_CRIT_SPECIFIED)
printf(" Lower Critical : %.3f\n", printf
sdr_convert_sensor_reading(sensor, rsp->data[2])); (" Lower Critical : %.3f\n",
sdr_convert_sensor_reading
(sensor, rsp->data[2]));
else else
printf(" Lower Critical : na\n"); printf
if (rsp->data[0] & LOWER_NON_CRIT_SPECIFIED) (" Lower Critical : na\n");
printf(" Lower Non-Critical : %.3f\n", if (rsp->
sdr_convert_sensor_reading(sensor, rsp->data[1])); data[0] & LOWER_NON_CRIT_SPECIFIED)
printf
(" Lower Non-Critical : %.3f\n",
sdr_convert_sensor_reading
(sensor, rsp->data[1]));
else else
printf(" Lower Non-Critical : na\n"); printf
if (rsp->data[0] & UPPER_NON_CRIT_SPECIFIED) (" Lower Non-Critical : na\n");
printf(" Upper Non-Critical : %.3f\n", if (rsp->
sdr_convert_sensor_reading(sensor, rsp->data[4])); data[0] & UPPER_NON_CRIT_SPECIFIED)
printf
(" Upper Non-Critical : %.3f\n",
sdr_convert_sensor_reading
(sensor, rsp->data[4]));
else else
printf(" Upper Non-Critical : na\n"); printf
(" Upper Non-Critical : na\n");
if (rsp->data[0] & UPPER_CRIT_SPECIFIED) if (rsp->data[0] & UPPER_CRIT_SPECIFIED)
printf(" Upper Critical : %.3f\n", printf
sdr_convert_sensor_reading(sensor, rsp->data[5])); (" Upper Critical : %.3f\n",
sdr_convert_sensor_reading
(sensor, rsp->data[5]));
else else
printf(" Upper Critical : na\n"); printf
if (rsp->data[0] & UPPER_NON_RECOV_SPECIFIED) (" Upper Critical : na\n");
printf(" Upper Non-Recoverable : %.3f\n", if (rsp->
sdr_convert_sensor_reading(sensor, rsp->data[6])); data[0] & UPPER_NON_RECOV_SPECIFIED)
printf
(" Upper Non-Recoverable : %.3f\n",
sdr_convert_sensor_reading
(sensor, rsp->data[6]));
else else
printf(" Upper Non-Recoverable : na\n"); printf
(" Upper Non-Recoverable : na\n");
} }
} } else {
else
{
printf("Not Present\n"); printf("Not Present\n");
} }
ipmi_sdr_print_sensor_event_status(intf,
sensor->keys.
sensor_num,
sensor->sensor.type,
sensor->event_type,
ANALOG_SENSOR);
ipmi_sdr_print_sensor_event_enable(intf,
sensor->keys.
sensor_num,
sensor->sensor.type,
sensor->event_type,
ANALOG_SENSOR);
printf("\n"); printf("\n");
} }
} }
return 0;
} }
int int
@ -396,7 +419,9 @@ ipmi_sensor_print_compact(struct ipmi_intf * intf,
/* /*
* Get current reading * Get current reading
*/ */
rsp = ipmi_sdr_get_sensor_reading(intf, sensor->keys.sensor_num); rsp = ipmi_sdr_get_sensor_reading_ipmb(intf,
sensor->keys.sensor_num,
sensor->keys.owner_id);
if (rsp == NULL) { if (rsp == NULL) {
lprintf(LOG_ERR, "Error reading sensor %s (#%02x)", lprintf(LOG_ERR, "Error reading sensor %s (#%02x)",
id, sensor->keys.sensor_num); id, sensor->keys.sensor_num);
@ -408,14 +433,10 @@ ipmi_sensor_print_compact(struct ipmi_intf * intf,
val = rsp->data[0]; val = rsp->data[0];
} }
if (csv_output) if (csv_output) {
{
/* NOT IMPLEMENTED */ /* NOT IMPLEMENTED */
} } else {
else if (!verbose) {
{
if (!verbose)
{
/* output format /* output format
* id value units status thresholds.... * id value units status thresholds....
*/ */
@ -433,16 +454,19 @@ ipmi_sensor_print_compact(struct ipmi_intf * intf,
printf("| %-10s| %-10s| %-10s| %-10s| %-10s| %-10s", printf("| %-10s| %-10s| %-10s| %-10s| %-10s| %-10s",
"na", "na", "na", "na", "na", "na"); "na", "na", "na", "na", "na", "na");
printf("\n"); printf("\n");
} } else {
else
{
printf("Sensor ID : %s (0x%x)\n", printf("Sensor ID : %s (0x%x)\n",
id, sensor->keys.sensor_num); id, sensor->keys.sensor_num);
printf(" Entity ID : %d.%d\n", printf(" Entity ID : %d.%d\n",
sensor->entity.id, sensor->entity.instance); sensor->entity.id, sensor->entity.instance);
printf(" Sensor Type (Discrete): %s\n", printf(" Sensor Type (Discrete): %s\n",
ipmi_sdr_get_sensor_type_desc(sensor->sensor.type)); ipmi_sdr_get_sensor_type_desc(sensor->sensor.
ipmi_sdr_print_discrete_state(sensor->sensor.type, sensor->event_type, rsp->data[2]); type));
ipmi_sdr_print_discrete_state("States Asserted",
sensor->sensor.type,
sensor->event_type,
rsp->data[2],
rsp->data[3]);
printf("\n"); printf("\n");
} }
} }
@ -465,24 +489,28 @@ ipmi_sensor_list(struct ipmi_intf * intf)
return -1; return -1;
} }
while ((header = ipmi_sdr_get_next_header(intf, itr)) != NULL) while ((header = ipmi_sdr_get_next_header(intf, itr)) != NULL) {
{
int r = 0; int r = 0;
uint8_t *rec; uint8_t *rec;
rec = ipmi_sdr_get_record(intf, header, itr); rec = ipmi_sdr_get_record(intf, header, itr);
if (rec == NULL) if (rec == NULL) {
lprintf(LOG_DEBUG, "rec == NULL");
continue; continue;
}
switch(header->type) switch (header->type) {
{
case SDR_RECORD_TYPE_FULL_SENSOR: case SDR_RECORD_TYPE_FULL_SENSOR:
r = ipmi_sensor_print_full(intf, r = ipmi_sensor_print_full(intf,
(struct sdr_record_full_sensor *)rec); (struct
sdr_record_full_sensor *)
rec);
break; break;
case SDR_RECORD_TYPE_COMPACT_SENSOR: case SDR_RECORD_TYPE_COMPACT_SENSOR:
r = ipmi_sensor_print_compact(intf, r = ipmi_sensor_print_compact(intf,
(struct sdr_record_compact_sensor *)rec); (struct
sdr_record_compact_sensor
*) rec);
break; break;
} }
free(rec); free(rec);
@ -507,34 +535,93 @@ static const struct valstr threshold_vals[] = {
}; };
static int static int
ipmi_sensor_set_threshold(struct ipmi_intf * intf, int argc, char ** argv) __ipmi_sensor_set_threshold(struct ipmi_intf *intf,
uint8_t num, uint8_t mask, uint8_t setting)
{ {
char * id, * thresh;
uint8_t settingMask;
float setting;
struct sdr_record_list * sdr;
struct ipmi_rs *rsp; struct ipmi_rs *rsp;
if (argc < 3 || strncmp(argv[0], "help", 4) == 0) rsp = ipmi_sensor_set_sensor_thresholds(intf, num, mask, setting);
{
lprintf(LOG_NOTICE, "sensor thresh <id> <threshold> <setting>"); if (rsp == NULL) {
lprintf(LOG_NOTICE, " id : name of the sensor for which threshold is to be set"); lprintf(LOG_ERR, "Error setting threshold");
lprintf(LOG_NOTICE, " threshold : which threshold to set"); return -1;
lprintf(LOG_NOTICE, " unr = upper non-recoverable"); }
lprintf(LOG_NOTICE, " ucr = upper critical"); if (rsp->ccode > 0) {
lprintf(LOG_NOTICE, " unc = upper non-critical"); lprintf(LOG_ERR, "Error setting threshold: %s",
lprintf(LOG_NOTICE, " lnc = lower non-critical"); val2str(rsp->ccode, completion_code_vals));
lprintf(LOG_NOTICE, " lcr = lower critical"); return -1;
lprintf(LOG_NOTICE, " lnr = lower non-recoverable"); }
lprintf(LOG_NOTICE, " setting : the value to set the threshold to");
return 0; return 0;
} }
ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN); static int
ipmi_sensor_set_threshold(struct ipmi_intf *intf, int argc, char **argv)
{
char *id, *thresh;
uint8_t settingMask = 0;
double setting1 = 0.0, setting2 = 0.0, setting3 = 0.0;
int allUpper = 0, allLower = 0;
int ret = 0;
struct sdr_record_list *sdr;
if (argc < 3 || strncmp(argv[0], "help", 4) == 0) {
lprintf(LOG_NOTICE, "sensor thresh <id> <threshold> <setting>");
lprintf(LOG_NOTICE,
" id : name of the sensor for which threshold is to be set");
lprintf(LOG_NOTICE, " threshold : which threshold to set");
lprintf(LOG_NOTICE,
" unr = upper non-recoverable");
lprintf(LOG_NOTICE, " ucr = upper critical");
lprintf(LOG_NOTICE,
" unc = upper non-critical");
lprintf(LOG_NOTICE,
" lnc = lower non-critical");
lprintf(LOG_NOTICE, " lcr = lower critical");
lprintf(LOG_NOTICE,
" lnr = lower non-recoverable");
lprintf(LOG_NOTICE,
" setting : the value to set the threshold to");
lprintf(LOG_NOTICE, "");
lprintf(LOG_NOTICE,
"sensor thresh <id> lower <lnr> <lcr> <lnc>");
lprintf(LOG_NOTICE,
" Set all lower thresholds at the same time");
lprintf(LOG_NOTICE, "");
lprintf(LOG_NOTICE,
"sensor thresh <id> upper <unc> <ucr> <unr>");
lprintf(LOG_NOTICE,
" Set all upper thresholds at the same time");
lprintf(LOG_NOTICE, "");
return 0;
}
id = argv[0]; id = argv[0];
thresh = argv[1]; thresh = argv[1];
setting = (float)atof(argv[2]);
if (strncmp(thresh, "upper", 5) == 0) {
if (argc < 5) {
lprintf(LOG_ERR,
"usage: sensor thresh <id> upper <unc> <ucr> <unr>");
return -1;
}
allUpper = 1;
setting1 = (double) strtod(argv[2], NULL);
setting2 = (double) strtod(argv[3], NULL);
setting3 = (double) strtod(argv[4], NULL);
} else if (strncmp(thresh, "lower", 5) == 0) {
if (argc < 5) {
lprintf(LOG_ERR,
"usage: sensor thresh <id> lower <unc> <ucr> <unr>");
return -1;
}
allLower = 1;
setting1 = (double) strtod(argv[2], NULL);
setting2 = (double) strtod(argv[3], NULL);
setting3 = (double) strtod(argv[4], NULL);
} else {
setting1 = (double) atof(argv[2]);
if (strncmp(thresh, "unr", 3) == 0) if (strncmp(thresh, "unr", 3) == 0)
settingMask = UPPER_NON_RECOV_SPECIFIED; settingMask = UPPER_NON_RECOV_SPECIFIED;
else if (strncmp(thresh, "ucr", 3) == 0) else if (strncmp(thresh, "ucr", 3) == 0)
@ -548,11 +635,14 @@ ipmi_sensor_set_threshold(struct ipmi_intf * intf, int argc, char ** argv)
else if (strncmp(thresh, "lnr", 3) == 0) else if (strncmp(thresh, "lnr", 3) == 0)
settingMask = LOWER_NON_RECOV_SPECIFIED; settingMask = LOWER_NON_RECOV_SPECIFIED;
else { else {
lprintf(LOG_ERR, "Valid threshold not specified!"); lprintf(LOG_ERR,
"Valid threshold '%s' for sensor '%s' not specified!",
thresh, id);
return -1; return -1;
} }
}
printf("Locating sensor record...\n"); printf("Locating sensor record '%s'...\n", id);
/* lookup by sensor name */ /* lookup by sensor name */
sdr = ipmi_sdr_find_sdr_byid(intf, id); sdr = ipmi_sdr_find_sdr_byid(intf, id);
@ -566,25 +656,79 @@ ipmi_sensor_set_threshold(struct ipmi_intf * intf, int argc, char ** argv)
return -1; return -1;
} }
if (allUpper) {
settingMask = UPPER_NON_CRIT_SPECIFIED;
printf("Setting sensor \"%s\" %s threshold to %.3f\n", printf("Setting sensor \"%s\" %s threshold to %.3f\n",
sdr->record.full->id_string, sdr->record.full->id_string,
val2str(settingMask, threshold_vals), setting); val2str(settingMask, threshold_vals), setting1);
ret = __ipmi_sensor_set_threshold(intf,
sdr->record.full->keys.
sensor_num, settingMask,
sdr_convert_sensor_value_to_raw
(sdr->record.full, setting1));
rsp = ipmi_sensor_set_sensor_thresholds(intf, settingMask = UPPER_CRIT_SPECIFIED;
sdr->record.full->keys.sensor_num, settingMask, printf("Setting sensor \"%s\" %s threshold to %.3f\n",
sdr_convert_sensor_value_to_raw(sdr->record.full, setting)); sdr->record.full->id_string,
val2str(settingMask, threshold_vals), setting2);
ret = __ipmi_sensor_set_threshold(intf,
sdr->record.full->keys.
sensor_num, settingMask,
sdr_convert_sensor_value_to_raw
(sdr->record.full, setting2));
if (rsp == NULL) { settingMask = UPPER_NON_RECOV_SPECIFIED;
lprintf(LOG_ERR, "Error setting threshold"); printf("Setting sensor \"%s\" %s threshold to %.3f\n",
return -1; sdr->record.full->id_string,
} val2str(settingMask, threshold_vals), setting3);
if (rsp->ccode > 0) { ret = __ipmi_sensor_set_threshold(intf,
lprintf(LOG_ERR, "Error setting threshold: %s", sdr->record.full->keys.
val2str(rsp->ccode, completion_code_vals)); sensor_num, settingMask,
return -1; sdr_convert_sensor_value_to_raw
(sdr->record.full, setting3));
} else if (allLower) {
settingMask = LOWER_NON_RECOV_SPECIFIED;
printf("Setting sensor \"%s\" %s threshold to %.3f\n",
sdr->record.full->id_string,
val2str(settingMask, threshold_vals), setting1);
ret = __ipmi_sensor_set_threshold(intf,
sdr->record.full->keys.
sensor_num, settingMask,
sdr_convert_sensor_value_to_raw
(sdr->record.full, setting1));
settingMask = LOWER_CRIT_SPECIFIED;
printf("Setting sensor \"%s\" %s threshold to %.3f\n",
sdr->record.full->id_string,
val2str(settingMask, threshold_vals), setting2);
ret = __ipmi_sensor_set_threshold(intf,
sdr->record.full->keys.
sensor_num, settingMask,
sdr_convert_sensor_value_to_raw
(sdr->record.full, setting2));
settingMask = LOWER_NON_CRIT_SPECIFIED;
printf("Setting sensor \"%s\" %s threshold to %.3f\n",
sdr->record.full->id_string,
val2str(settingMask, threshold_vals), setting3);
ret = __ipmi_sensor_set_threshold(intf,
sdr->record.full->keys.
sensor_num, settingMask,
sdr_convert_sensor_value_to_raw
(sdr->record.full, setting3));
} else {
printf("Setting sensor \"%s\" %s threshold to %.3f\n",
sdr->record.full->id_string,
val2str(settingMask, threshold_vals), setting1);
ret = __ipmi_sensor_set_threshold(intf,
sdr->record.full->keys.
sensor_num, settingMask,
sdr_convert_sensor_value_to_raw
(sdr->record.full, setting1));
} }
return 0; return ret;
} }
static int static int
@ -621,16 +765,22 @@ ipmi_sensor_get(struct ipmi_intf * intf, int argc, char ** argv)
r = ipmi_sensor_print_full(intf, sdr->record.full); r = ipmi_sensor_print_full(intf, sdr->record.full);
break; break;
case SDR_RECORD_TYPE_COMPACT_SENSOR: case SDR_RECORD_TYPE_COMPACT_SENSOR:
r = ipmi_sensor_print_compact(intf, sdr->record.compact); r = ipmi_sensor_print_compact(intf,
sdr->record.compact);
break; break;
case SDR_RECORD_TYPE_EVENTONLY_SENSOR: case SDR_RECORD_TYPE_EVENTONLY_SENSOR:
r = ipmi_sdr_print_sensor_eventonly(intf, sdr->record.eventonly); r = ipmi_sdr_print_sensor_eventonly(intf,
sdr->record.
eventonly);
break; break;
case SDR_RECORD_TYPE_FRU_DEVICE_LOCATOR: case SDR_RECORD_TYPE_FRU_DEVICE_LOCATOR:
r = ipmi_sdr_print_sensor_fru_locator(intf, sdr->record.fruloc); r = ipmi_sdr_print_sensor_fru_locator(intf,
sdr->record.
fruloc);
break; break;
case SDR_RECORD_TYPE_MC_DEVICE_LOCATOR: case SDR_RECORD_TYPE_MC_DEVICE_LOCATOR:
r = ipmi_sdr_print_sensor_mc_locator(intf, sdr->record.mcloc); r = ipmi_sdr_print_sensor_mc_locator(intf,
sdr->record.mcloc);
break; break;
} }
verbose = v; verbose = v;
@ -649,22 +799,16 @@ ipmi_sensor_main(struct ipmi_intf * intf, int argc, char ** argv)
if (argc == 0) { if (argc == 0) {
rc = ipmi_sensor_list(intf); rc = ipmi_sensor_list(intf);
} } else if (strncmp(argv[0], "help", 4) == 0) {
else if (strncmp(argv[0], "help", 4) == 0) {
lprintf(LOG_NOTICE, "Sensor Commands: list thresh get"); lprintf(LOG_NOTICE, "Sensor Commands: list thresh get");
} } else if (strncmp(argv[0], "list", 4) == 0) {
else if (strncmp(argv[0], "list", 4) == 0) {
rc = ipmi_sensor_list(intf); rc = ipmi_sensor_list(intf);
} } else if (strncmp(argv[0], "thresh", 5) == 0) {
else if (strncmp(argv[0], "thresh", 5) == 0) {
rc = ipmi_sensor_set_threshold(intf, argc - 1, &argv[1]); rc = ipmi_sensor_set_threshold(intf, argc - 1, &argv[1]);
} } else if (strncmp(argv[0], "get", 3) == 0) {
else if (strncmp(argv[0], "get", 3) == 0) {
rc = ipmi_sensor_get(intf, argc - 1, &argv[1]); rc = ipmi_sensor_get(intf, argc - 1, &argv[1]);
} } else {
else { lprintf(LOG_ERR, "Invalid sensor command: %s", argv[0]);
lprintf(LOG_ERR, "Invalid sensor command: %s",
argv[0]);
rc = -1; rc = -1;
} }

View File

@ -97,11 +97,19 @@ print_session_info_csv(const struct get_session_info_rsp * session_info,
if (data_len == 18) if (data_len == 18)
{ {
/* We have 802.3 LAN data */ /* We have 802.3 LAN data */
#ifdef __CYGWIN__
printf(",%d.%d.%d.%d",
session_info->channel_data.lan_data.console_ip[0],
session_info->channel_data.lan_data.console_ip[1],
session_info->channel_data.lan_data.console_ip[2],
session_info->channel_data.lan_data.console_ip[3]);
#else
printf(",%s", printf(",%s",
inet_ntop(AF_INET, inet_ntop(AF_INET,
&(session_info->channel_data.lan_data.console_ip), &(session_info->channel_data.lan_data.console_ip),
buffer, buffer,
16)); 16));
#endif
printf(",%02x:%02x:%02x:%02x:%02x:%02x", printf(",%02x:%02x:%02x:%02x:%02x:%02x",
session_info->channel_data.lan_data.console_mac[0], session_info->channel_data.lan_data.console_mac[0],
@ -129,11 +137,19 @@ print_session_info_csv(const struct get_session_info_rsp * session_info,
printf(",%d", printf(",%d",
session_info->channel_data.modem_data.destination_selector); session_info->channel_data.modem_data.destination_selector);
#ifdef __CYGWIN__
printf(",%d.%d.%d.%d",
session_info->channel_data.modem_data.console_ip[0],
session_info->channel_data.modem_data.console_ip[1],
session_info->channel_data.modem_data.console_ip[2],
session_info->channel_data.modem_data.console_ip[3]);
#else
printf(",%s", printf(",%s",
inet_ntop(AF_INET, inet_ntop(AF_INET,
&(session_info->channel_data.modem_data.console_ip), &(session_info->channel_data.modem_data.console_ip),
buffer, buffer,
16)); 16));
#endif
if (data_len == 14) if (data_len == 14)
{ {
@ -185,11 +201,19 @@ print_session_info_verbose(const struct get_session_info_rsp * session_info,
if (data_len == 18) if (data_len == 18)
{ {
/* We have 802.3 LAN data */ /* We have 802.3 LAN data */
#ifdef __CYGWIN__
printf("console ip : %d.%d.%d.%d\n",
session_info->channel_data.lan_data.console_ip[0],
session_info->channel_data.lan_data.console_ip[1],
session_info->channel_data.lan_data.console_ip[2],
session_info->channel_data.lan_data.console_ip[3]);
#else
printf("console ip : %s\n", printf("console ip : %s\n",
inet_ntop(AF_INET, inet_ntop(AF_INET,
&(session_info->channel_data.lan_data.console_ip), &(session_info->channel_data.lan_data.console_ip),
buffer, buffer,
16)); 16));
#endif
printf("console mac : %02x:%02x:%02x:%02x:%02x:%02x\n", printf("console mac : %02x:%02x:%02x:%02x:%02x:%02x\n",
session_info->channel_data.lan_data.console_mac[0], session_info->channel_data.lan_data.console_mac[0],
@ -217,11 +241,19 @@ print_session_info_verbose(const struct get_session_info_rsp * session_info,
printf("Destination selector : %d\n", printf("Destination selector : %d\n",
session_info->channel_data.modem_data.destination_selector); session_info->channel_data.modem_data.destination_selector);
#ifdef __CYGWIN__
printf("console ip : %d.%d.%d.%d\n",
session_info->channel_data.modem_data.console_ip[0],
session_info->channel_data.modem_data.console_ip[1],
session_info->channel_data.modem_data.console_ip[2],
session_info->channel_data.modem_data.console_ip[3]);
#else
printf("console ip : %s\n", printf("console ip : %s\n",
inet_ntop(AF_INET, inet_ntop(AF_INET,
&(session_info->channel_data.modem_data.console_ip), &(session_info->channel_data.modem_data.console_ip),
buffer, buffer,
16)); 16));
#endif
if (data_len == 14) if (data_len == 14)
{ {
@ -317,7 +349,7 @@ ipmi_get_session_info(struct ipmi_intf * intf,
if (retval < 0) if (retval < 0)
{ {
if ((session_request_type == IPMI_SESSION_REQUEST_CURRENT) && if ((session_request_type == IPMI_SESSION_REQUEST_CURRENT) &&
(strncmp(intf->name, "intf_lan", 8) != 0)) (strncmp(intf->name, "lan", 3) != 0))
lprintf(LOG_ERR, "It is likely that the channel in use " lprintf(LOG_ERR, "It is likely that the channel in use "
"does not support sessions"); "does not support sessions");
} }
@ -367,8 +399,8 @@ ipmi_get_session_info(struct ipmi_intf * intf,
void static void
printf_session_usage() printf_session_usage(void)
{ {
lprintf(LOG_NOTICE, "Session Commands: info <active | all | id 0xnnnnnnnn | handle 0xnn>"); lprintf(LOG_NOTICE, "Session Commands: info <active | all | id 0xnnnnnnnn | handle 0xnn>");
} }

View File

@ -36,8 +36,10 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <strings.h>
#include <stdio.h> #include <stdio.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h>
#include <sys/select.h> #include <sys/select.h>
#include <sys/time.h> #include <sys/time.h>
#include <signal.h> #include <signal.h>
@ -65,7 +67,19 @@
#define SOL_PARAMETER_SOL_PAYLOAD_CHANNEL 0x07 #define SOL_PARAMETER_SOL_PAYLOAD_CHANNEL 0x07
#define SOL_PARAMETER_SOL_PAYLOAD_PORT 0x08 #define SOL_PARAMETER_SOL_PAYLOAD_PORT 0x08
#define SOL_ESCAPE_CHARACTER '~' const struct valstr sol_parameter_vals[] = {
{ SOL_PARAMETER_SET_IN_PROGRESS, "Set In Progress (0)" },
{ SOL_PARAMETER_SOL_ENABLE, "Enable (1)" },
{ SOL_PARAMETER_SOL_AUTHENTICATION, "Authentication (2)" },
{ SOL_PARAMETER_CHARACTER_INTERVAL, "Character Interval (3)" },
{ SOL_PARAMETER_SOL_RETRY, "Retry (4)" },
{ SOL_PARAMETER_SOL_NON_VOLATILE_BIT_RATE, "Nonvolatile Bitrate (5)" },
{ SOL_PARAMETER_SOL_VOLATILE_BIT_RATE, "Volatile Bitrate (6)" },
{ SOL_PARAMETER_SOL_PAYLOAD_CHANNEL, "Payload Channel (7)" },
{ SOL_PARAMETER_SOL_PAYLOAD_PORT, "Payload Port (8)" },
{ 0x00, NULL },
};
static struct termios _saved_tio; static struct termios _saved_tio;
static int _in_raw_mode = 0; static int _in_raw_mode = 0;
@ -86,6 +100,7 @@ ipmi_get_sol_info(
struct ipmi_rq req; struct ipmi_rq req;
uint8_t data[4]; uint8_t data[4];
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_TRANSPORT; req.msg.netfn = IPMI_NETFN_TRANSPORT;
req.msg.cmd = IMPI_GET_SOL_CONFIG_PARAMETERS; req.msg.cmd = IMPI_GET_SOL_CONFIG_PARAMETERS;
req.msg.data_len = 4; req.msg.data_len = 4;
@ -102,22 +117,33 @@ ipmi_get_sol_info(
data[3] = 0x00; /* block selector */ data[3] = 0x00; /* block selector */
rsp = intf->sendrecv(intf, &req); rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode) {
lprintf(LOG_ERR, "Error:%x Error requesting SOL parameter %d",
rsp ? rsp->ccode : 0,
data[1]);
return -1;
}
if (rsp->data_len != 2)
{
lprintf(LOG_ERR, "Error: Unexpected data length (%d) received "
"for SOL paraemeter %d",
rsp->data_len,
data[1]);
return -1;
}
params->set_in_progress = rsp->data[1];
if (NULL != rsp) {
switch (rsp->ccode) {
case 0x00:
if (rsp->data_len == 2) {
params->set_in_progress = rsp->data[1];
} else {
lprintf(LOG_ERR, "Error: Unexpected data length (%d) received "
"for SOL parameter '%s'",
rsp->data_len,
val2str(data[1], sol_parameter_vals));
}
break;
case 0x80:
lprintf(LOG_ERR, "Info: SOL parameter '%s' not supported",
val2str(data[1], sol_parameter_vals));
break;
default:
lprintf(LOG_ERR, "Error requesting SOL parameter '%s': %s",
val2str(data[1], sol_parameter_vals),
val2str(rsp->ccode, completion_code_vals));
return -1;
}
} else {
lprintf(LOG_ERR, "Error: No response requesting SOL parameter '%s'",
val2str(data[1], sol_parameter_vals));
}
/* /*
* SOL enable * SOL enable
@ -129,22 +155,33 @@ ipmi_get_sol_info(
data[3] = 0x00; /* block selector */ data[3] = 0x00; /* block selector */
rsp = intf->sendrecv(intf, &req); rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode) {
lprintf(LOG_ERR, "Error:%x Error requesting SOL parameter %d",
rsp ? rsp->ccode : 0,
data[1]);
return -1;
}
if (rsp->data_len != 2)
{
lprintf(LOG_ERR, "Error: Unexpected data length (%d) received "
"for SOL paraemeter %d",
rsp->data_len,
data[1]);
return -1;
}
params->enabled = rsp->data[1];
if (NULL != rsp) {
switch (rsp->ccode) {
case 0x00:
if (rsp->data_len == 2) {
params->enabled = rsp->data[1];
} else {
lprintf(LOG_ERR, "Error: Unexpected data length (%d) received "
"for SOL parameter '%s'",
rsp->data_len,
val2str(data[1], sol_parameter_vals));
}
break;
case 0x80:
lprintf(LOG_ERR, "Info: SOL parameter '%s' not supported",
val2str(data[1], sol_parameter_vals));
break;
default:
lprintf(LOG_ERR, "Error requesting SOL parameter '%s': %s",
val2str(data[1], sol_parameter_vals),
val2str(rsp->ccode, completion_code_vals));
return -1;
}
} else {
lprintf(LOG_ERR, "Error: No response requesting SOL parameter '%s'",
val2str(data[1], sol_parameter_vals));
}
/* /*
* SOL authentication * SOL authentication
@ -156,24 +193,34 @@ ipmi_get_sol_info(
data[3] = 0x00; /* block selector */ data[3] = 0x00; /* block selector */
rsp = intf->sendrecv(intf, &req); rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode) { if (NULL != rsp) {
lprintf(LOG_ERR, "Error:%x Error requesting SOL parameter %d", switch (rsp->ccode) {
rsp ? rsp->ccode : 0, case 0x00:
data[1]); if (rsp->data_len == 2) {
return -1;
}
if (rsp->data_len != 2)
{
lprintf(LOG_ERR, "Error: Unexpected data length (%d) received "
"for SOL paraemeter %d",
rsp->data_len,
data[1]);
return -1;
}
params->force_encryption = ((rsp->data[1] & 0x80)? 1 : 0); params->force_encryption = ((rsp->data[1] & 0x80)? 1 : 0);
params->force_authentication = ((rsp->data[1] & 0x40)? 1 : 0); params->force_authentication = ((rsp->data[1] & 0x40)? 1 : 0);
params->privilege_level = rsp->data[1] & 0x0F; params->privilege_level = rsp->data[1] & 0x0F;
} else {
lprintf(LOG_ERR, "Error: Unexpected data length (%d) received "
"for SOL parameter '%s'",
rsp->data_len,
val2str(data[1], sol_parameter_vals));
}
break;
case 0x80:
lprintf(LOG_ERR, "Info: SOL parameter '%s' not supported",
val2str(data[1], sol_parameter_vals));
break;
default:
lprintf(LOG_ERR, "Error requesting SOL parameter '%s': %s",
val2str(data[1], sol_parameter_vals),
val2str(rsp->ccode, completion_code_vals));
return -1;
}
} else {
lprintf(LOG_ERR, "Error: No response requesting SOL parameter '%s'",
val2str(data[1], sol_parameter_vals));
}
/* /*
* Character accumulate interval and character send interval * Character accumulate interval and character send interval
@ -185,23 +232,33 @@ ipmi_get_sol_info(
data[3] = 0x00; /* block selector */ data[3] = 0x00; /* block selector */
rsp = intf->sendrecv(intf, &req); rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode) { if (NULL != rsp) {
lprintf(LOG_ERR, "Error:%x Error requesting SOL parameter %d", switch (rsp->ccode) {
rsp ? rsp->ccode : 0, case 0x00:
data[1]); if (rsp->data_len == 3) {
return -1;
}
if (rsp->data_len != 3)
{
lprintf(LOG_ERR, "Error: Unexpected data length (%d) received "
"for SOL paraemeter %d",
rsp->data_len,
data[1]);
return -1;
}
params->character_accumulate_level = rsp->data[1]; params->character_accumulate_level = rsp->data[1];
params->character_send_threshold = rsp->data[2]; params->character_send_threshold = rsp->data[2];
} else {
lprintf(LOG_ERR, "Error: Unexpected data length (%d) received "
"for SOL parameter '%s'",
rsp->data_len,
val2str(data[1], sol_parameter_vals));
}
break;
case 0x80:
lprintf(LOG_ERR, "Info: SOL parameter '%s' not supported",
val2str(data[1], sol_parameter_vals));
break;
default:
lprintf(LOG_ERR, "Error requesting SOL parameter '%s': %s",
val2str(data[1], sol_parameter_vals),
val2str(rsp->ccode, completion_code_vals));
return -1;
}
} else {
lprintf(LOG_ERR, "Error: No response requesting SOL parameter '%s'",
val2str(data[1], sol_parameter_vals));
}
/* /*
* SOL retry * SOL retry
@ -213,23 +270,33 @@ ipmi_get_sol_info(
data[3] = 0x00; /* block selector */ data[3] = 0x00; /* block selector */
rsp = intf->sendrecv(intf, &req); rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode) { if (NULL != rsp) {
lprintf(LOG_ERR, "Error:%x Error requesting SOL parameter %d", switch (rsp->ccode) {
rsp ? rsp->ccode : 0, case 0x00:
data[1]); if (rsp->data_len == 3) {
return -1;
}
if (rsp->data_len != 3)
{
lprintf(LOG_ERR, "Error: Unexpected data length (%d) received "
"for SOL paraemeter %d",
rsp->data_len,
data[1]);
return -1;
}
params->retry_count = rsp->data[1]; params->retry_count = rsp->data[1];
params->retry_interval = rsp->data[2]; params->retry_interval = rsp->data[2];
} else {
lprintf(LOG_ERR, "Error: Unexpected data length (%d) received "
"for SOL parameter '%s'",
rsp->data_len,
val2str(data[1], sol_parameter_vals));
}
break;
case 0x80:
lprintf(LOG_ERR, "Info: SOL parameter '%s' not supported",
val2str(data[1], sol_parameter_vals));
break;
default:
lprintf(LOG_ERR, "Error requesting SOL parameter '%s': %s",
val2str(data[1], sol_parameter_vals),
val2str(rsp->ccode, completion_code_vals));
return -1;
}
} else {
lprintf(LOG_ERR, "Error: No response requesting SOL parameter '%s'",
val2str(data[1], sol_parameter_vals));
}
/* /*
* SOL non-volatile bit rate * SOL non-volatile bit rate
@ -241,22 +308,32 @@ ipmi_get_sol_info(
data[3] = 0x00; /* block selector */ data[3] = 0x00; /* block selector */
rsp = intf->sendrecv(intf, &req); rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode) { if (NULL != rsp) {
lprintf(LOG_ERR, "Error:%x Error requesting SOL parameter %d", switch (rsp->ccode) {
rsp ? rsp->ccode : 0, case 0x00:
data[1]); if (rsp->data_len == 2) {
return -1;
}
if (rsp->data_len != 2)
{
lprintf(LOG_ERR, "Error: Unexpected data length (%d) received "
"for SOL paraemeter %d",
rsp->data_len,
data[1]);
return -1;
}
params->non_volatile_bit_rate = rsp->data[1] & 0x0F; params->non_volatile_bit_rate = rsp->data[1] & 0x0F;
} else {
lprintf(LOG_ERR, "Error: Unexpected data length (%d) received "
"for SOL parameter '%s'",
rsp->data_len,
val2str(data[1], sol_parameter_vals));
}
break;
case 0x80:
lprintf(LOG_ERR, "Info: SOL parameter '%s' not supported",
val2str(data[1], sol_parameter_vals));
break;
default:
lprintf(LOG_ERR, "Error requesting SOL parameter '%s': %s",
val2str(data[1], sol_parameter_vals),
val2str(rsp->ccode, completion_code_vals));
return -1;
}
} else {
lprintf(LOG_ERR, "Error: No response requesting SOL parameter '%s'",
val2str(data[1], sol_parameter_vals));
}
/* /*
* SOL volatile bit rate * SOL volatile bit rate
@ -268,22 +345,32 @@ ipmi_get_sol_info(
data[3] = 0x00; /* block selector */ data[3] = 0x00; /* block selector */
rsp = intf->sendrecv(intf, &req); rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode) { if (NULL != rsp) {
lprintf(LOG_ERR, "Error:%x Error requesting SOL parameter %d", switch (rsp->ccode) {
rsp ? rsp->ccode : 0, case 0x00:
data[1]); if (rsp->data_len == 2) {
return -1;
}
if (rsp->data_len != 2)
{
lprintf(LOG_ERR, "Error: Unexpected data length (%d) received "
"for SOL paraemeter %d",
rsp->data_len,
data[1]);
return -1;
}
params->volatile_bit_rate = rsp->data[1] & 0x0F; params->volatile_bit_rate = rsp->data[1] & 0x0F;
} else {
lprintf(LOG_ERR, "Error: Unexpected data length (%d) received "
"for SOL parameter '%s'",
rsp->data_len,
val2str(data[1], sol_parameter_vals));
}
break;
case 0x80:
lprintf(LOG_ERR, "Info: SOL parameter '%s' not supported",
val2str(data[1], sol_parameter_vals));
break;
default:
lprintf(LOG_ERR, "Error requesting SOL parameter '%s': %s",
val2str(data[1], sol_parameter_vals),
val2str(rsp->ccode, completion_code_vals));
return -1;
}
} else {
lprintf(LOG_ERR, "Error: No response requesting SOL parameter '%s'",
val2str(data[1], sol_parameter_vals));
}
/* /*
* SOL payload channel * SOL payload channel
@ -295,22 +382,33 @@ ipmi_get_sol_info(
data[3] = 0x00; /* block selector */ data[3] = 0x00; /* block selector */
rsp = intf->sendrecv(intf, &req); rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode) { if (NULL != rsp) {
lprintf(LOG_ERR, "Error:%x Error requesting SOL parameter %d", switch (rsp->ccode) {
rsp ? rsp->ccode : 0, case 0x00:
data[1]); if (rsp->data_len == 2) {
return -1;
}
if (rsp->data_len != 2)
{
lprintf(LOG_ERR, "Error: Unexpected data length (%d) received "
"for SOL paraemeter %d",
rsp->data_len,
data[1]);
return -1;
}
params->payload_channel = rsp->data[1]; params->payload_channel = rsp->data[1];
} else {
lprintf(LOG_ERR, "Error: Unexpected data length (%d) received "
"for SOL parameter '%s'",
rsp->data_len,
val2str(data[1], sol_parameter_vals));
}
break;
case 0x80:
lprintf(LOG_ERR, "Info: SOL parameter '%s' not supported - defaulting to 0x%02x",
val2str(data[1], sol_parameter_vals), channel);
params->payload_channel = channel;
break;
default:
lprintf(LOG_ERR, "Error requesting SOL parameter '%s': %s",
val2str(data[1], sol_parameter_vals),
val2str(rsp->ccode, completion_code_vals));
return -1;
}
} else {
lprintf(LOG_ERR, "Error: No response requesting SOL parameter '%s'",
val2str(data[1], sol_parameter_vals));
}
/* /*
* SOL payload port * SOL payload port
@ -322,21 +420,33 @@ ipmi_get_sol_info(
data[3] = 0x00; /* block selector */ data[3] = 0x00; /* block selector */
rsp = intf->sendrecv(intf, &req); rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode) { if (NULL != rsp) {
lprintf(LOG_ERR, "Error:%x Error requesting SOL parameter %d", switch (rsp->ccode) {
rsp ? rsp->ccode : 0, case 0x00:
data[1]); if (rsp->data_len == 3) {
return -1;
}
if (rsp->data_len != 3)
{
lprintf(LOG_ERR, "Error: Unexpected data length (%d) "
"received for SOL paraemeter %d",
rsp->data_len,
data[1]);
return -1;
}
params->payload_port = (rsp->data[1]) | (rsp->data[2] << 8); params->payload_port = (rsp->data[1]) | (rsp->data[2] << 8);
} else {
lprintf(LOG_ERR, "Error: Unexpected data length (%d) received "
"for SOL parameter '%s'",
rsp->data_len,
val2str(data[1], sol_parameter_vals));
}
break;
case 0x80:
lprintf(LOG_ERR, "Info: SOL parameter '%s' not supported - defaulting to %d",
val2str(data[1], sol_parameter_vals), intf->session->port);
params->payload_port = intf->session->port;
break;
default:
lprintf(LOG_ERR, "Error requesting SOL parameter '%s': %s",
val2str(data[1], sol_parameter_vals),
val2str(rsp->ccode, completion_code_vals));
return -1;
}
} else {
lprintf(LOG_ERR, "Error: No response requesting SOL parameter '%s'",
val2str(data[1], sol_parameter_vals));
}
return 0; return 0;
} }
@ -349,7 +459,7 @@ ipmi_get_sol_info(
static int static int
ipmi_print_sol_info(struct ipmi_intf * intf, uint8_t channel) ipmi_print_sol_info(struct ipmi_intf * intf, uint8_t channel)
{ {
struct sol_config_parameters params; struct sol_config_parameters params = {0};
if (ipmi_get_sol_info(intf, channel, &params)) if (ipmi_get_sol_info(intf, channel, &params))
return -1; return -1;
@ -405,8 +515,8 @@ ipmi_print_sol_info(struct ipmi_intf * intf, uint8_t channel)
printf("Non-Volatile Bit Rate (kbps) : %s\n", printf("Non-Volatile Bit Rate (kbps) : %s\n",
val2str(params.non_volatile_bit_rate, impi_bit_rate_vals)); val2str(params.non_volatile_bit_rate, impi_bit_rate_vals));
printf("Payload Channel : %d\n", printf("Payload Channel : %d (0x%02x)\n",
params.payload_channel); params.payload_channel, params.payload_channel);
printf("Payload Port : %d\n", printf("Payload Port : %d\n",
params.payload_port); params.payload_port);
} }
@ -436,6 +546,7 @@ ipmi_sol_set_param(struct ipmi_intf * intf,
uint8_t data[4]; uint8_t data[4];
int bGuarded = 1; /* Use set-in-progress indicator? */ int bGuarded = 1; /* Use set-in-progress indicator? */
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_TRANSPORT; /* 0x0c */ req.msg.netfn = IPMI_NETFN_TRANSPORT; /* 0x0c */
req.msg.cmd = IMPI_SET_SOL_CONFIG_PARAMETERS; /* 0x21 */ req.msg.cmd = IMPI_SET_SOL_CONFIG_PARAMETERS; /* 0x21 */
req.msg.data = data; req.msg.data = data;
@ -658,7 +769,7 @@ ipmi_sol_set_param(struct ipmi_intf * intf,
req.msg.data_len = 4; req.msg.data_len = 4;
data[1] = SOL_PARAMETER_SOL_RETRY; data[1] = SOL_PARAMETER_SOL_RETRY;
data[2] = (uint8_t)strtol(value, NULL, 0) & 0x03; data[2] = (uint8_t)strtol(value, NULL, 0) & 0x07;
/* We need other values to complete the request */ /* We need other values to complete the request */
if (ipmi_get_sol_info(intf, channel, &params)) if (ipmi_get_sol_info(intf, channel, &params))
@ -804,11 +915,14 @@ ipmi_sol_set_param(struct ipmi_intf * intf,
/* The command proper */ /* The command proper */
rsp = intf->sendrecv(intf, &req); rsp = intf->sendrecv(intf, &req);
if (rsp == NULL) {
lprintf(LOG_ERR, "Error setting SOL parameter '%s'", param);
return -1;
}
if (!rsp || rsp->ccode) { if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Error:%x Error setting SOL parameter %s", lprintf(LOG_ERR, "Error setting SOL parameter '%s': %s",
rsp ? rsp->ccode : 0, param, val2str(rsp->ccode, completion_code_vals));
param);
if (bGuarded && if (bGuarded &&
(ipmi_sol_set_param(intf, (ipmi_sol_set_param(intf,
@ -931,8 +1045,8 @@ suspendSelf(int bRestoreTty)
* *
* Send some useful documentation to the user * Send some useful documentation to the user
*/ */
void static void
printSolEscapeSequences() printSolEscapeSequences(struct ipmi_intf * intf)
{ {
printf( printf(
"%c?\r\n\ "%c?\r\n\
@ -944,14 +1058,14 @@ printSolEscapeSequences()
%c? - this message\r\n\ %c? - this message\r\n\
%c%c - send the escape character by typing it twice\r\n\ %c%c - send the escape character by typing it twice\r\n\
(Note that escapes are only recognized immediately after newline.)\r\n", (Note that escapes are only recognized immediately after newline.)\r\n",
SOL_ESCAPE_CHARACTER, intf->session->sol_escape_char,
SOL_ESCAPE_CHARACTER, intf->session->sol_escape_char,
SOL_ESCAPE_CHARACTER, intf->session->sol_escape_char,
SOL_ESCAPE_CHARACTER, intf->session->sol_escape_char,
SOL_ESCAPE_CHARACTER, intf->session->sol_escape_char,
SOL_ESCAPE_CHARACTER, intf->session->sol_escape_char,
SOL_ESCAPE_CHARACTER, intf->session->sol_escape_char,
SOL_ESCAPE_CHARACTER); intf->session->sol_escape_char);
} }
@ -986,6 +1100,7 @@ ipmi_sol_deactivate(struct ipmi_intf * intf)
struct ipmi_rq req; struct ipmi_rq req;
uint8_t data[6]; uint8_t data[6];
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_APP; req.msg.netfn = IPMI_NETFN_APP;
req.msg.cmd = IPMI_DEACTIVATE_PAYLOAD; req.msg.cmd = IPMI_DEACTIVATE_PAYLOAD;
req.msg.data_len = 6; req.msg.data_len = 6;
@ -1003,13 +1118,26 @@ ipmi_sol_deactivate(struct ipmi_intf * intf)
rsp = intf->sendrecv(intf, &req); rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode) { if (NULL != rsp) {
lprintf(LOG_ERR, "Error:%x Dectivating SOL payload", switch (rsp->ccode) {
rsp ? rsp->ccode : 0); case 0x00:
return -1; return 0;
case 0x80:
lprintf(LOG_ERR, "Info: SOL payload already de-activated");
break;
case 0x81:
lprintf(LOG_ERR, "Info: SOL payload type disabled");
break;
default:
lprintf(LOG_ERR, "Error de-activating SOL payload: %s",
val2str(rsp->ccode, completion_code_vals));
break;
}
} else {
lprintf(LOG_ERR, "Error: No response de-activating SOL payload");
} }
return 0; return -1;
} }
@ -1056,38 +1184,44 @@ processSolUserInput(
*/ */
switch (ch) { switch (ch) {
case '.': case '.':
printf("%c. [terminated ipmitool]\r\n", SOL_ESCAPE_CHARACTER); printf("%c. [terminated ipmitool]\r\n",
intf->session->sol_escape_char);
retval = 1; retval = 1;
break; break;
case 'Z' - 64: case 'Z' - 64:
printf("%c^Z [suspend ipmitool]\r\n", SOL_ESCAPE_CHARACTER); printf("%c^Z [suspend ipmitool]\r\n",
intf->session->sol_escape_char);
suspendSelf(1); /* Restore tty back to raw */ suspendSelf(1); /* Restore tty back to raw */
continue; continue;
case 'X' - 64: case 'X' - 64:
printf("%c^Z [suspend ipmitool]\r\n", SOL_ESCAPE_CHARACTER); printf("%c^Z [suspend ipmitool]\r\n",
intf->session->sol_escape_char);
suspendSelf(0); /* Don't restore to raw mode */ suspendSelf(0); /* Don't restore to raw mode */
continue; continue;
case 'B': case 'B':
printf("%cb [send break]\r\n", SOL_ESCAPE_CHARACTER); printf("%cb [send break]\r\n",
intf->session->sol_escape_char);
sendBreak(intf); sendBreak(intf);
continue; continue;
case '?': case '?':
printSolEscapeSequences(); printSolEscapeSequences(intf);
continue; continue;
default: default:
if (ch != SOL_ESCAPE_CHARACTER) if (ch != intf->session->sol_escape_char)
v2_payload.payload.sol_packet.data[length++] = v2_payload.payload.sol_packet.data[length++] =
SOL_ESCAPE_CHARACTER; intf->session->sol_escape_char;
v2_payload.payload.sol_packet.data[length++] = ch; v2_payload.payload.sol_packet.data[length++] = ch;
} }
} }
else else
{ {
if (last_was_cr && (ch == SOL_ESCAPE_CHARACTER)) { if (last_was_cr && (ch == intf->session->sol_escape_char)) {
escape_pending = 1; escape_pending = 1;
continue; continue;
} }
@ -1283,6 +1417,7 @@ ipmi_sol_activate(struct ipmi_intf * intf)
intf->session->sol_data.sol_input_handler = output; intf->session->sol_data.sol_input_handler = output;
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_APP; req.msg.netfn = IPMI_NETFN_APP;
req.msg.cmd = IPMI_ACTIVATE_PAYLOAD; req.msg.cmd = IPMI_ACTIVATE_PAYLOAD;
req.msg.data_len = 6; req.msg.data_len = 6;
@ -1303,18 +1438,43 @@ ipmi_sol_activate(struct ipmi_intf * intf)
rsp = intf->sendrecv(intf, &req); rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode) { if (NULL != rsp) {
lprintf(LOG_ERR, "Error:%x Activating SOL payload", switch (rsp->ccode) {
rsp ? rsp->ccode : 0); case 0x00:
return -1; if (rsp->data_len == 12) {
} break;
if (rsp->data_len != 12) } else {
{
lprintf(LOG_ERR, "Error: Unexpected data length (%d) received " lprintf(LOG_ERR, "Error: Unexpected data length (%d) received "
"in payload activation response", "in payload activation response",
rsp->data_len); rsp->data_len);
return -1; return -1;
} }
break;
case 0x80:
lprintf(LOG_ERR, "Info: SOL payload already active on another session");
return -1;
case 0x81:
lprintf(LOG_ERR, "Info: SOL payload disabled");
return -1;
case 0x82:
lprintf(LOG_ERR, "Info: SOL payload activation limit reached");
return -1;
case 0x83:
lprintf(LOG_ERR, "Info: cannot activate SOL payload with encryption");
return -1;
case 0x84:
lprintf(LOG_ERR, "Info: cannot activate SOL payload without encryption");
return -1;
default:
lprintf(LOG_ERR, "Error activating SOL payload: %s",
val2str(rsp->ccode, completion_code_vals));
return -1;
}
} else {
lprintf(LOG_ERR, "Error: No response activating SOL payload");
return -1;
}
memcpy(&ap_rsp, rsp->data, sizeof(struct activate_payload_rsp)); memcpy(&ap_rsp, rsp->data, sizeof(struct activate_payload_rsp));
@ -1345,15 +1505,25 @@ ipmi_sol_activate(struct ipmi_intf * intf)
intf->session->timeout = 3; intf->session->timeout = 3;
/* NOTE: the spec does allow for SOL traffic to be sent on
* a different port. we do not yet support that feature. */
if (intf->session->sol_data.port != intf->session->port) if (intf->session->sol_data.port != intf->session->port)
{ {
/* try byteswapping port in case BMC sent it incorrectly */
uint16_t portswap = BSWAP_16(intf->session->sol_data.port);
if (portswap == intf->session->port) {
intf->session->sol_data.port = portswap;
}
else {
lprintf(LOG_ERR, "Error: BMC requests SOL session on different port"); lprintf(LOG_ERR, "Error: BMC requests SOL session on different port");
return -1; return -1;
} }
}
printf("[SOL Session operational. Use %c? for help]\r\n", printf("[SOL Session operational. Use %c? for help]\r\n",
SOL_ESCAPE_CHARACTER); intf->session->sol_escape_char);
/* /*
@ -1376,8 +1546,8 @@ ipmi_sol_activate(struct ipmi_intf * intf)
/* /*
* print_sol_usage * print_sol_usage
*/ */
void static void
print_sol_usage() print_sol_usage(void)
{ {
lprintf(LOG_NOTICE, "SOL Commands: info [<channel number>]"); lprintf(LOG_NOTICE, "SOL Commands: info [<channel number>]");
lprintf(LOG_NOTICE, " set <parameter> <value> [channel]"); lprintf(LOG_NOTICE, " set <parameter> <value> [channel]");
@ -1390,8 +1560,8 @@ print_sol_usage()
/* /*
* print_sol_set_usage * print_sol_set_usage
*/ */
void static void
print_sol_set_usage() print_sol_set_usage(void)
{ {
lprintf(LOG_NOTICE, "\nSOL set parameters and values: \n"); lprintf(LOG_NOTICE, "\nSOL set parameters and values: \n");
lprintf(LOG_NOTICE, " set-in-progress set-complete | " lprintf(LOG_NOTICE, " set-in-progress set-complete | "

View File

@ -38,7 +38,30 @@
#include <ipmitool/ipmi_strings.h> #include <ipmitool/ipmi_strings.h>
#include <ipmitool/ipmi_constants.h> #include <ipmitool/ipmi_constants.h>
#include <ipmitool/ipmi_sensor.h> #include <ipmitool/ipmi_sensor.h>
#include <ipmitool/ipmi_sel.h> /* for IPMI_OEM */
const struct valstr ipmi_oem_info[] = {
{ IPMI_OEM_UNKNOWN, "Unknown" },
{ IPMI_OEM_SUN, "Sun Microsystems" },
{ IPMI_OEM_INTEL, "Intel Corporation" },
{ IPMI_OEM_TYAN, "Tyan Computer Corporation" },
{ IPMI_OEM_NEWISYS, "Newisys" },
{ IPMI_OEM_SUPERMICRO, "Supermicro" },
{ IPMI_OEM_KONTRON, "Kontron" },
{ 0xffff , NULL },
};
const struct valstr ipmi_netfn_vals[] = {
{ IPMI_NETFN_CHASSIS, "Chassis" },
{ IPMI_NETFN_BRIDGE, "Bridge" },
{ IPMI_NETFN_SE, "SensorEvent" },
{ IPMI_NETFN_APP, "Application" },
{ IPMI_NETFN_FIRMWARE, "Firmware" },
{ IPMI_NETFN_STORAGE, "Storage" },
{ IPMI_NETFN_TRANSPORT, "Transport" },
{ 0xff, NULL },
};
/* /*
* From table 26-4 of the IPMI v2 specification * From table 26-4 of the IPMI v2 specification
@ -69,7 +92,7 @@ const struct valstr ipmi_privlvl_vals[] = {
{ IPMI_SESSION_PRIV_ADMIN, "ADMINISTRATOR" }, { IPMI_SESSION_PRIV_ADMIN, "ADMINISTRATOR" },
{ IPMI_SESSION_PRIV_OEM, "OEM" }, { IPMI_SESSION_PRIV_OEM, "OEM" },
{ 0xF, "NO ACCESS" }, { 0xF, "NO ACCESS" },
{ 0, NULL }, { 0xFF, NULL },
}; };
@ -87,7 +110,7 @@ const struct valstr ipmi_authtype_session_vals[] = {
{ IPMI_SESSION_AUTHTYPE_MD5, "MD5" }, { IPMI_SESSION_AUTHTYPE_MD5, "MD5" },
{ IPMI_SESSION_AUTHTYPE_PASSWORD, "PASSWORD" }, { IPMI_SESSION_AUTHTYPE_PASSWORD, "PASSWORD" },
{ IPMI_SESSION_AUTHTYPE_OEM, "OEM" }, { IPMI_SESSION_AUTHTYPE_OEM, "OEM" },
{ 0, NULL }, { 0xFF, NULL },
}; };
@ -142,6 +165,18 @@ const struct valstr entity_id_vals[] = {
{ 0x26, "Remote Management Device" }, { 0x26, "Remote Management Device" },
{ 0x27, "External Environment" }, { 0x27, "External Environment" },
{ 0x28, "Battery" }, { 0x28, "Battery" },
{ 0x29, "Processing Blade" },
{ 0x2A, "Connectivity Switch" },
{ 0x2B, "Processor/Memory Module" },
{ 0x2C, "I/O Module" },
{ 0x2D, "Processor/IO Module" },
{ 0x2E, "Management Controller Firmware" },
{ 0x2F, "IPMI Channel" },
{ 0x30, "PCI Bus" },
{ 0x31, "PCI Express Bus" },
{ 0x32, "SCSI Bus (parallel)" },
{ 0x33, "SATA/SAS Bus" },
{ 0x34, "Processor/Front-Side Bus" },
{ 0x00, NULL }, { 0x00, NULL },
}; };
@ -211,7 +246,7 @@ const struct valstr ipmi_channel_protocol_vals[] = {
const struct valstr ipmi_channel_medium_vals[] = { const struct valstr ipmi_channel_medium_vals[] = {
{ IPMI_CHANNEL_MEDIUM_RESERVED, "reserved" }, { IPMI_CHANNEL_MEDIUM_RESERVED, "reserved" },
{ IPMI_CHANNEL_MEDIUM_IPMB, "IPMB (I2C)" }, { IPMI_CHANNEL_MEDIUM_IPMB_I2C, "IPMB (I2C)" },
{ IPMI_CHANNEL_MEDIUM_ICMB_1, "ICMB v1.0" }, { IPMI_CHANNEL_MEDIUM_ICMB_1, "ICMB v1.0" },
{ IPMI_CHANNEL_MEDIUM_ICMB_09, "ICMB v0.9" }, { IPMI_CHANNEL_MEDIUM_ICMB_09, "ICMB v0.9" },
{ IPMI_CHANNEL_MEDIUM_LAN, "802.3 LAN" }, { IPMI_CHANNEL_MEDIUM_LAN, "802.3 LAN" },
@ -254,3 +289,35 @@ const struct valstr completion_code_vals[] = {
{ 0x00, NULL } { 0x00, NULL }
}; };
const struct valstr ipmi_chassis_power_control_vals[] = {
{ IPMI_CHASSIS_CTL_POWER_DOWN, "Down/Off" },
{ IPMI_CHASSIS_CTL_POWER_UP, "Up/On" },
{ IPMI_CHASSIS_CTL_POWER_CYCLE, "Cycle" },
{ IPMI_CHASSIS_CTL_HARD_RESET, "Reset" },
{ IPMI_CHASSIS_CTL_PULSE_DIAG, "Diag" },
{ IPMI_CHASSIS_CTL_ACPI_SOFT, "Soft" },
{ 0x00, NULL },
};
const struct valstr ipmi_auth_algorithms[] = {
{ IPMI_AUTH_RAKP_NONE, "none" },
{ IPMI_AUTH_RAKP_HMAC_SHA1, "hmac_sha1" },
{ IPMI_AUTH_RAKP_HMAC_MD5, "hmac_md5" },
{ 0x00, NULL }
};
const struct valstr ipmi_integrity_algorithms[] = {
{ IPMI_INTEGRITY_NONE, "none" },
{ IPMI_INTEGRITY_HMAC_SHA1_96, "hmac_sha1_96" },
{ IPMI_INTEGRITY_HMAC_MD5_128, "hmac_md5_128" },
{ IPMI_INTEGRITY_MD5_128 , "md5_128" },
{ 0x00, NULL }
};
const struct valstr ipmi_encryption_algorithms[] = {
{ IPMI_CRYPT_NONE, "none" },
{ IPMI_CRYPT_AES_CBC_128, "aes_cbc_128" },
{ IPMI_CRYPT_XRC4_128, "xrc4_128" },
{ IPMI_CRYPT_XRC4_40, "xrc4_40" },
{ 0x00, NULL }
};

794
ipmitool/lib/ipmi_sunoem.c Normal file
View File

@ -0,0 +1,794 @@
/*
* Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistribution of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistribution in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind.
* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
* SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE
* FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
* SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
* OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
* PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
* LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed or intended for use
* in the design, construction, operation or maintenance of any nuclear
* facility.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <ctype.h>
#include <ipmitool/ipmi.h>
#include <ipmitool/ipmi_intf.h>
#include <ipmitool/helper.h>
#include <ipmitool/log.h>
#include <ipmitool/ipmi_sel.h>
#include <ipmitool/ipmi_sdr.h>
#include <ipmitool/ipmi_strings.h>
#include <ipmitool/ipmi_channel.h>
#include <ipmitool/ipmi_sunoem.h>
#include <ipmitool/ipmi_raw.h>
static const struct valstr sunoem_led_type_vals[] = {
{ 0, "OK2RM" },
{ 1, "SERVICE" },
{ 2, "ACT" },
{ 3, "LOCATE" },
{ 0, NULL },
};
static const struct valstr sunoem_led_mode_vals[] = {
{ 0, "OFF" },
{ 1, "ON" },
{ 2, "STANDBY" },
{ 3, "SLOW" },
{ 4, "FAST" },
{ 0xFF, NULL },
};
static const struct valstr sunoem_led_mode_optvals[] = {
{ 0, "STEADY_OFF" },
{ 1, "STEADY_ON" },
{ 2, "STANDBY_BLINK" },
{ 3, "SLOW_BLINK" },
{ 4, "FAST_BLINK" },
{ 0xFF, NULL },
};
static void
ipmi_sunoem_usage(void)
{
lprintf(LOG_NOTICE, "usage: sunoem <command> [option...]");
lprintf(LOG_NOTICE, "");
lprintf(LOG_NOTICE, " fan speed <0-100>");
lprintf(LOG_NOTICE, " Set system fan speed (PWM duty cycle)");
lprintf(LOG_NOTICE, "");
lprintf(LOG_NOTICE, " sshkey set <userid> <id_rsa.pub>");
lprintf(LOG_NOTICE, " Set ssh key for a userid into authorized_keys,");
lprintf(LOG_NOTICE, " view users with 'user list' command.");
lprintf(LOG_NOTICE, "");
lprintf(LOG_NOTICE, " sshkey del <userid>");
lprintf(LOG_NOTICE, " Delete ssh key for userid from authorized_keys,");
lprintf(LOG_NOTICE, " view users with 'user list' command.");
lprintf(LOG_NOTICE, "");
lprintf(LOG_NOTICE, " led get <sensorid> [ledtype]");
lprintf(LOG_NOTICE, " Read status of LED found in Generic Device Locator.");
lprintf(LOG_NOTICE, "");
lprintf(LOG_NOTICE, " led set <sensorid> <ledmode> [ledtype]");
lprintf(LOG_NOTICE, " Set mode of LED found in Generic Device Locator.");
lprintf(LOG_NOTICE, "");
lprintf(LOG_NOTICE, " Use 'sdr list generic' command to get list of Generic");
lprintf(LOG_NOTICE, " Devices that are controllable LEDs.");
lprintf(LOG_NOTICE, "");
lprintf(LOG_NOTICE, " Required SIS LED Mode:");
lprintf(LOG_NOTICE, " OFF Off");
lprintf(LOG_NOTICE, " ON Steady On");
lprintf(LOG_NOTICE, " STANDBY 100ms on 2900ms off blink rate");
lprintf(LOG_NOTICE, " SLOW 1HZ blink rate");
lprintf(LOG_NOTICE, " FAST 4HZ blink rate");
lprintf(LOG_NOTICE, "");
lprintf(LOG_NOTICE, " Optional SIS LED Type:");
lprintf(LOG_NOTICE, " OK2RM OK to Remove");
lprintf(LOG_NOTICE, " SERVICE Service Required");
lprintf(LOG_NOTICE, " ACT Activity");
lprintf(LOG_NOTICE, " LOCATE Locate");
lprintf(LOG_NOTICE, "");
}
/*
* IPMI Request Data: 1 byte
*
* [byte 0] FanSpeed Fan speed as percentage
*/
static int
ipmi_sunoem_fan_speed(struct ipmi_intf * intf, uint8_t speed)
{
struct ipmi_rs * rsp;
struct ipmi_rq req;
/*
* sunoem fan speed <percent>
*/
if (speed > 100) {
lprintf(LOG_NOTICE, "Invalid fan speed: %d", speed);
return -1;
}
req.msg.netfn = IPMI_NETFN_SUNOEM;
req.msg.cmd = IPMI_SUNOEM_SET_FAN_SPEED;
req.msg.data = &speed;
req.msg.data_len = 1;
rsp = intf->sendrecv(intf, &req);
if (rsp == NULL) {
lprintf(LOG_ERR, "Sun OEM Set Fan Speed command failed");
return -1;
}
else if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Sun OEM Set Fan Speed command failed: %s",
val2str(rsp->ccode, completion_code_vals));
return -1;
}
printf("Set Fan speed to %d%%\n", speed);
return 0;
}
static void
__sdr_list_empty(struct sdr_record_list * head)
{
struct sdr_record_list * e, * f;
for (e = head; e != NULL; e = f) {
f = e->next;
free(e);
}
head = NULL;
}
static void
led_print(const char * name, uint8_t state)
{
if (csv_output)
printf("%s,%s\n", name, val2str(state, sunoem_led_mode_vals));
else
printf("%-16s | %s\n", name, val2str(state, sunoem_led_mode_vals));
}
struct ipmi_rs *
sunoem_led_get(struct ipmi_intf * intf,
struct sdr_record_generic_locator * dev,
int ledtype)
{
struct ipmi_rs * rsp;
struct ipmi_rq req;
uint8_t rqdata[5];
if (dev == NULL)
return NULL;
rqdata[0] = dev->dev_slave_addr;
rqdata[1] = ledtype;
rqdata[2] = dev->dev_access_addr;
rqdata[3] = dev->oem;
rqdata[4] = 0;
req.msg.netfn = IPMI_NETFN_SUNOEM;
req.msg.cmd = IPMI_SUNOEM_LED_GET;
req.msg.data = rqdata;
req.msg.data_len = 5;
rsp = intf->sendrecv(intf, &req);
if (rsp == NULL) {
lprintf(LOG_ERR, "Sun OEM Get LED command failed");
return NULL;
}
else if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Sun OEM Get LED command failed: %s",
val2str(rsp->ccode, completion_code_vals));
return NULL;
}
return rsp;
}
struct ipmi_rs *
sunoem_led_set(struct ipmi_intf * intf,
struct sdr_record_generic_locator * dev,
int ledtype, int ledmode)
{
struct ipmi_rs * rsp;
struct ipmi_rq req;
uint8_t rqdata[7];
if (dev == NULL)
return NULL;
rqdata[0] = dev->dev_slave_addr;
rqdata[1] = ledtype;
rqdata[2] = dev->dev_access_addr;
rqdata[3] = dev->oem;
rqdata[4] = ledmode;
rqdata[5] = 0;
rqdata[6] = 0;
req.msg.netfn = IPMI_NETFN_SUNOEM;
req.msg.cmd = IPMI_SUNOEM_LED_SET;
req.msg.data = rqdata;
req.msg.data_len = 7;
rsp = intf->sendrecv(intf, &req);
if (rsp == NULL) {
lprintf(LOG_ERR, "Sun OEM Set LED command failed");
return NULL;
}
else if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Sun OEM Set LED command failed: %s",
val2str(rsp->ccode, completion_code_vals));
return NULL;
}
return rsp;
}
static void
sunoem_led_get_byentity(struct ipmi_intf * intf, uint8_t entity_id,
uint8_t entity_inst, int ledtype)
{
struct ipmi_rs * rsp;
struct sdr_record_list *elist, *e;
struct entity_id entity;
if (entity_id == 0)
return;
/* lookup sdrs with this entity */
memset(&entity, 0, sizeof(struct entity_id));
entity.id = entity_id;
entity.instance = entity_inst;
elist = ipmi_sdr_find_sdr_byentity(intf, &entity);
/* for each generic sensor set its led state */
for (e = elist; e != NULL; e = e->next) {
if (e->type != SDR_RECORD_TYPE_GENERIC_DEVICE_LOCATOR)
continue;
rsp = sunoem_led_get(intf, e->record.genloc, ledtype);
if (rsp && rsp->data_len == 1) {
led_print((const char *)e->record.genloc->id_string, rsp->data[0]);
}
}
__sdr_list_empty(elist);
}
static void
sunoem_led_set_byentity(struct ipmi_intf * intf, uint8_t entity_id,
uint8_t entity_inst, int ledtype, int ledmode)
{
struct ipmi_rs * rsp;
struct sdr_record_list *elist, *e;
struct entity_id entity;
if (entity_id == 0)
return;
/* lookup sdrs with this entity */
memset(&entity, 0, sizeof(struct entity_id));
entity.id = entity_id;
entity.instance = entity_inst;
elist = ipmi_sdr_find_sdr_byentity(intf, &entity);
/* for each generic sensor set its led state */
for (e = elist; e != NULL; e = e->next) {
if (e->type != SDR_RECORD_TYPE_GENERIC_DEVICE_LOCATOR)
continue;
rsp = sunoem_led_set(intf, e->record.genloc, ledtype, ledmode);
if (rsp && rsp->data_len == 0) {
led_print((const char *)e->record.genloc->id_string, ledmode);
}
}
__sdr_list_empty(elist);
}
/*
* IPMI Request Data: 5 bytes
*
* [byte 0] devAddr Value from the "Device Slave Address" field in
* LED's Generic Device Locator record in the SDR
* [byte 1] led LED Type: OK2RM, ACT, LOCATE, SERVICE
* [byte 2] ctrlrAddr Controller address; value from the "Device
* Access Address" field, 0x20 if the LED is local
* [byte 3] hwInfo The OEM field from the SDR record
* [byte 4] force 1 = directly access the device
* 0 = go thru its controller
* Ignored if LED is local
*/
static int
ipmi_sunoem_led_get(struct ipmi_intf * intf, int argc, char ** argv)
{
struct ipmi_rs * rsp;
struct sdr_record_list *sdr;
struct sdr_record_list *alist, *a;
struct sdr_record_entity_assoc *assoc;
int ledtype = 0;
int i;
/*
* sunoem led get <id> [type]
*/
if (argc < 1 || strncmp(argv[0], "help", 4) == 0) {
lprintf(LOG_NOTICE, "usage: sunoem led get <id> [type]");
return 0;
}
if (argc > 1) {
ledtype = str2val(argv[1], sunoem_led_type_vals);
}
if (strncasecmp(argv[0], "all", 3) == 0) {
/* do all generic sensors */
alist = ipmi_sdr_find_sdr_bytype(intf, SDR_RECORD_TYPE_GENERIC_DEVICE_LOCATOR);
for (a = alist; a != NULL; a = a->next) {
if (a->type != SDR_RECORD_TYPE_GENERIC_DEVICE_LOCATOR)
continue;
if (a->record.genloc->entity.logical)
continue;
rsp = sunoem_led_get(intf, a->record.genloc, ledtype);
if (rsp && rsp->data_len == 1) {
led_print((const char *)a->record.genloc->id_string, rsp->data[0]);
}
}
__sdr_list_empty(alist);
return 0;
}
/* look up generic device locator record in SDR */
sdr = ipmi_sdr_find_sdr_byid(intf, argv[0]);
if (sdr == NULL) {
lprintf(LOG_ERR, "No Sensor Data Record found for %s", argv[0]);
return -1;
}
if (sdr->type != SDR_RECORD_TYPE_GENERIC_DEVICE_LOCATOR) {
lprintf(LOG_ERR, "Invalid SDR type %d", sdr->type);
return -1;
}
if (!sdr->record.genloc->entity.logical) {
/*
* handle physical entity
*/
rsp = sunoem_led_get(intf, sdr->record.genloc, ledtype);
if (rsp && rsp->data_len == 1) {
led_print((const char *)sdr->record.genloc->id_string, rsp->data[0]);
}
return 0;
}
/*
* handle logical entity for LED grouping
*/
lprintf(LOG_INFO, "LED %s is logical device", argv[0]);
/* get entity assoc records */
alist = ipmi_sdr_find_sdr_bytype(intf, SDR_RECORD_TYPE_ENTITY_ASSOC);
for (a = alist; a != NULL; a = a->next) {
if (a->type != SDR_RECORD_TYPE_ENTITY_ASSOC)
continue;
assoc = a->record.entassoc;
if (assoc == NULL)
continue;
/* check that the entity id/instance matches our generic record */
if (assoc->entity.id != sdr->record.genloc->entity.id ||
assoc->entity.instance != sdr->record.genloc->entity.instance)
continue;
if (assoc->flags.isrange) {
/*
* handle ranged entity associations
*
* the test for non-zero entity id is handled in
* sunoem_led_get_byentity()
*/
/* first range set - id 1 and 2 must be equal */
if (assoc->entity_id_1 == assoc->entity_id_2)
for (i = assoc->entity_inst_1; i <= assoc->entity_inst_2; i++)
sunoem_led_get_byentity(intf, assoc->entity_id_1, i, ledtype);
/* second range set - id 3 and 4 must be equal */
if (assoc->entity_id_3 == assoc->entity_id_4)
for (i = assoc->entity_inst_3; i <= assoc->entity_inst_4; i++)
sunoem_led_get_byentity(intf, assoc->entity_id_3, i, ledtype);
}
else {
/*
* handle entity list
*/
sunoem_led_get_byentity(intf, assoc->entity_id_1,
assoc->entity_inst_1, ledtype);
sunoem_led_get_byentity(intf, assoc->entity_id_2,
assoc->entity_inst_2, ledtype);
sunoem_led_get_byentity(intf, assoc->entity_id_3,
assoc->entity_inst_3, ledtype);
sunoem_led_get_byentity(intf, assoc->entity_id_4,
assoc->entity_inst_4, ledtype);
}
}
__sdr_list_empty(alist);
return 0;
}
/*
* IPMI Request Data: 7 bytes
*
* [byte 0] devAddr Value from the "Device Slave Address" field in
* LED's Generic Device Locator record in the SDR
* [byte 1] led LED Type: OK2RM, ACT, LOCATE, SERVICE
* [byte 2] ctrlrAddr Controller address; value from the "Device
* Access Address" field, 0x20 if the LED is local
* [byte 3] hwInfo The OEM field from the SDR record
* [byte 4] mode LED Mode: OFF, ON, STANDBY, SLOW, FAST
* [byte 5] force TRUE - directly access the device
* FALSE - go thru its controller
* Ignored if LED is local
* [byte 6] role Used by BMC for authorization purposes
*
*
* IPMI Response Data: 1 byte
*
* [byte 0] mode LED Mode: OFF, ON, STANDBY, SLOW, FAST
*/
static int
ipmi_sunoem_led_set(struct ipmi_intf * intf, int argc, char ** argv)
{
struct ipmi_rs * rsp;
struct sdr_record_list *sdr;
struct sdr_record_list *alist, *a;
struct sdr_record_entity_assoc *assoc;
int ledmode;
int ledtype = 0;
int i;
/*
* sunoem led set <id> <mode> [type]
*/
if (argc < 2 || strncmp(argv[0], "help", 4) == 0) {
ipmi_sunoem_usage();
return 0;
}
ledmode = str2val(argv[1], sunoem_led_mode_vals);
if (ledmode == 0xFF) {
ledmode = str2val(argv[1], sunoem_led_mode_optvals);
if (ledmode == 0xFF) {
lprintf(LOG_NOTICE, "Invalid LED Mode: %s", argv[1]);
return -1;
}
}
if (argc > 3) {
ledtype = str2val(argv[2], sunoem_led_type_vals);
}
if (strncasecmp(argv[0], "all", 3) == 0) {
/* do all generic sensors */
alist = ipmi_sdr_find_sdr_bytype(intf, SDR_RECORD_TYPE_GENERIC_DEVICE_LOCATOR);
for (a = alist; a != NULL; a = a->next) {
if (a->type != SDR_RECORD_TYPE_GENERIC_DEVICE_LOCATOR)
continue;
if (a->record.genloc->entity.logical)
continue;
rsp = sunoem_led_set(intf, a->record.genloc, ledtype, ledmode);
if (rsp && rsp->ccode == 0) {
led_print((const char *)a->record.genloc->id_string, ledmode);
}
}
__sdr_list_empty(alist);
return 0;
}
/* look up generic device locator records in SDR */
sdr = ipmi_sdr_find_sdr_byid(intf, argv[0]);
if (sdr == NULL) {
lprintf(LOG_ERR, "No Sensor Data Record found for %s",
argv[0]);
return -1;
}
if (sdr->type != SDR_RECORD_TYPE_GENERIC_DEVICE_LOCATOR) {
lprintf(LOG_ERR, "Invalid SDR type %d", sdr->type);
return -1;
}
if (!sdr->record.genloc->entity.logical) {
/*
* handle physical entity
*/
rsp = sunoem_led_set(intf, sdr->record.genloc, ledtype, ledmode);
if (rsp && rsp->ccode == 0) {
led_print(argv[0], ledmode);
}
return 0;
}
/*
* handle logical entity for LED grouping
*/
lprintf(LOG_INFO, "LED %s is logical device", argv[0]);
/* get entity assoc records */
alist = ipmi_sdr_find_sdr_bytype(intf, SDR_RECORD_TYPE_ENTITY_ASSOC);
for (a = alist; a != NULL; a = a->next) {
if (a->type != SDR_RECORD_TYPE_ENTITY_ASSOC)
continue;
assoc = a->record.entassoc;
if (assoc == NULL)
continue;
/* check that the entity id/instance matches our generic record */
if (assoc->entity.id != sdr->record.genloc->entity.id ||
assoc->entity.instance != sdr->record.genloc->entity.instance)
continue;
if (assoc->flags.isrange) {
/*
* handle ranged entity associations
*
* the test for non-zero entity id is handled in
* sunoem_led_get_byentity()
*/
/* first range set - id 1 and 2 must be equal */
if (assoc->entity_id_1 == assoc->entity_id_2)
for (i = assoc->entity_inst_1; i <= assoc->entity_inst_2; i++)
sunoem_led_set_byentity(intf, assoc->entity_id_1, i, ledtype, ledmode);
/* second range set - id 3 and 4 must be equal */
if (assoc->entity_id_3 == assoc->entity_id_4)
for (i = assoc->entity_inst_3; i <= assoc->entity_inst_4; i++)
sunoem_led_set_byentity(intf, assoc->entity_id_3, i, ledtype, ledmode);
}
else {
/*
* handle entity list
*/
sunoem_led_set_byentity(intf, assoc->entity_id_1,
assoc->entity_inst_1, ledtype, ledmode);
sunoem_led_set_byentity(intf, assoc->entity_id_2,
assoc->entity_inst_2, ledtype, ledmode);
sunoem_led_set_byentity(intf, assoc->entity_id_3,
assoc->entity_inst_3, ledtype, ledmode);
sunoem_led_set_byentity(intf, assoc->entity_id_4,
assoc->entity_inst_4, ledtype, ledmode);
}
}
__sdr_list_empty(alist);
return 0;
}
static int
ipmi_sunoem_sshkey_del(struct ipmi_intf * intf, uint8_t uid)
{
struct ipmi_rs * rsp;
struct ipmi_rq req;
memset(&req, 0, sizeof(struct ipmi_rq));
req.msg.netfn = IPMI_NETFN_SUNOEM;
req.msg.cmd = IPMI_SUNOEM_DEL_SSH_KEY;
req.msg.data = &uid;
req.msg.data_len = 1;
rsp = intf->sendrecv(intf, &req);
if (rsp == NULL) {
lprintf(LOG_ERR, "Unable to delete ssh key for UID %d", uid);
return -1;
}
else if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Unable to delete ssh key for UID %d: %s", uid,
val2str(rsp->ccode, completion_code_vals));
return -1;
}
printf("Deleted SSH key for user id %d\n", uid);
return 0;
}
#define SSHKEY_BLOCK_SIZE 64
static int
ipmi_sunoem_sshkey_set(struct ipmi_intf * intf, uint8_t uid, char * ifile)
{
struct ipmi_rs * rsp;
struct ipmi_rq req;
FILE * fp;
int count;
uint16_t i_size, r, size;
uint8_t wbuf[SSHKEY_BLOCK_SIZE + 3];
if (ifile == NULL) {
lprintf(LOG_ERR, "Invalid or misisng input filename");
return -1;
}
fp = ipmi_open_file_read(ifile);
if (fp == NULL) {
lprintf(LOG_ERR, "Unable to open file %s for reading", ifile);
return -1;
}
printf("Setting SSH key for user id %d...", uid);
memset(&req, 0, sizeof(struct ipmi_rq));
req.msg.netfn = IPMI_NETFN_SUNOEM;
req.msg.cmd = IPMI_SUNOEM_SET_SSH_KEY;
req.msg.data = wbuf;
fseek(fp, 0, SEEK_END);
size = ftell(fp);
fseek(fp, 0, SEEK_SET);
for (r = 0; r < size; r += i_size) {
i_size = size - r;
if (i_size > SSHKEY_BLOCK_SIZE)
i_size = SSHKEY_BLOCK_SIZE;
memset(wbuf, 0, SSHKEY_BLOCK_SIZE);
fseek(fp, r, SEEK_SET);
count = fread(wbuf+3, 1, i_size, fp);
if (count != i_size) {
lprintf(LOG_ERR, "Unable to read %d bytes from file %s", i_size, ifile);
fclose(fp);
return -1;
}
printf(".");
fflush(stdout);
wbuf[0] = uid;
if ((r + SSHKEY_BLOCK_SIZE) >= size)
wbuf[1] = 0xff;
else
wbuf[1] = (uint8_t)(r / SSHKEY_BLOCK_SIZE);
wbuf[2] = i_size;
req.msg.data_len = i_size + 3;
rsp = intf->sendrecv(intf, &req);
if (rsp == NULL) {
lprintf(LOG_ERR, "Unable to set ssh key for UID %d", uid);
break;
}
}
printf("done\n");
fclose(fp);
return 0;
}
int
ipmi_sunoem_main(struct ipmi_intf * intf, int argc, char ** argv)
{
int rc = 0;
if (argc == 0 || strncmp(argv[0], "help", 4) == 0) {
ipmi_sunoem_usage();
return 0;
}
if (strncmp(argv[0], "fan", 3) == 0) {
uint8_t pct;
if (argc < 2) {
ipmi_sunoem_usage();
return -1;
}
else if (strncmp(argv[1], "speed", 5) == 0) {
if (argc < 3) {
ipmi_sunoem_usage();
return -1;
}
pct = (uint8_t)strtol(argv[2], NULL, 0);
rc = ipmi_sunoem_fan_speed(intf, pct);
}
else {
ipmi_sunoem_usage();
return -1;
}
}
if (strncmp(argv[0], "led", 3) == 0) {
if (argc < 2) {
ipmi_sunoem_usage();
return -1;
}
if (strncmp(argv[1], "get", 3) == 0) {
if (argc < 3) {
char * arg[] = { "all" };
rc = ipmi_sunoem_led_get(intf, 1, arg);
} else {
rc = ipmi_sunoem_led_get(intf, argc-2, &(argv[2]));
}
}
else if (strncmp(argv[1], "set", 3) == 0) {
if (argc < 4) {
ipmi_sunoem_usage();
return -1;
}
rc = ipmi_sunoem_led_set(intf, argc-2, &(argv[2]));
}
else {
ipmi_sunoem_usage();
return -1;
}
}
if (strncmp(argv[0], "sshkey", 6) == 0) {
if (argc < 2) {
ipmi_sunoem_usage();
return -1;
}
else if (strncmp(argv[1], "del", 3) == 0) {
uint8_t uid;
if (argc < 3) {
ipmi_sunoem_usage();
return -1;
}
uid = (uint8_t)strtoul(argv[2], NULL, 0);
rc = ipmi_sunoem_sshkey_del(intf, uid);
}
else if (strncmp(argv[1], "set", 3) == 0) {
uint8_t uid;
if (argc < 4) {
ipmi_sunoem_usage();
return -1;
}
uid = (uint8_t)strtoul(argv[2], NULL, 0);
rc = ipmi_sunoem_sshkey_set(intf, uid, argv[3]);
}
}
return rc;
}

596
ipmitool/lib/ipmi_tsol.c Normal file
View File

@ -0,0 +1,596 @@
/*
* Copyright (c) 2005 Tyan Computer Corp. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistribution of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistribution in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind.
* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
* SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE
* FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
* SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
* OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
* PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
* LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed or intended for use
* in the design, construction, operation or maintenance of any nuclear
* facility.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/poll.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <signal.h>
#include <sys/select.h>
#include <sys/time.h>
#ifdef __linux__
# include <linux/termios.h>
#else
# include <sys/termios.h>
#endif
#include <ipmitool/log.h>
#include <ipmitool/helper.h>
#include <ipmitool/ipmi.h>
#include <ipmitool/ipmi_intf.h>
#include <ipmitool/ipmi_tsol.h>
#include <ipmitool/ipmi_strings.h>
#include <ipmitool/bswap.h>
#include <config.h>
static struct timeval _start_keepalive;
static struct termios _saved_tio;
static struct winsize _saved_winsize;
static int _in_raw_mode = 0;
static int _altterm = 0;
static int
ipmi_tsol_command(struct ipmi_intf * intf, char *recvip, int port, unsigned char cmd)
{
struct ipmi_rs *rsp;
struct ipmi_rq req;
unsigned char data[6];
unsigned ip1, ip2, ip3, ip4;
uint16_t portin;
#if WORDS_BIGENDIAN
portin = BSWAP_16(port);
#else
portin = port;
#endif
if (sscanf(recvip, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4) != 4) {
lprintf(LOG_ERR, "Invalid IP address: %s", recvip);
return -1;
}
req.msg.netfn = IPMI_NETFN_TSOL;
req.msg.cmd = cmd;
req.msg.data_len = 6;
req.msg.data = data;
memset(data, 0, sizeof(data));
data[0] = ip1;
data[1] = ip2;
data[2] = ip3;
data[3] = ip4;
data[4] = (portin & 0xff00) >> 8;
data[5] = (portin & 0xff);
rsp = intf->sendrecv(intf, &req);
if (rsp == NULL) {
lprintf(LOG_ERR, "Unable to perform TSOL command");
return -1;
}
if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Unable to perform TSOL command: %s",
val2str(rsp->ccode, completion_code_vals));
return -1;
}
return 0;
}
static int
ipmi_tsol_start(struct ipmi_intf * intf, char *recvip, int port)
{
return ipmi_tsol_command(intf, recvip, port, IPMI_TSOL_CMD_START);
}
static int
ipmi_tsol_stop(struct ipmi_intf * intf, char *recvip, int port)
{
return ipmi_tsol_command(intf, recvip, port, IPMI_TSOL_CMD_STOP);
}
static int
ipmi_tsol_send_keystroke(struct ipmi_intf * intf, char *buff, int length)
{
struct ipmi_rs * rsp;
struct ipmi_rq req;
unsigned char data[16];
static unsigned char keyseq = 0;
req.msg.netfn = IPMI_NETFN_TSOL;
req.msg.cmd = IPMI_TSOL_CMD_SENDKEY;
req.msg.data_len = length + 2;
req.msg.data = data;
memset(data, 0, sizeof(data));
data[0] = length + 1;
memcpy(data + 1, buff, length);
data[length + 1] = keyseq++;
rsp = intf->sendrecv(intf, &req);
if (rsp == NULL) {
lprintf(LOG_ERR, "Unable to send keystroke");
return -1;
}
if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Unable to send keystroke: %s",
val2str(rsp->ccode, completion_code_vals));
return -1;
}
return length;
}
static int
tsol_keepalive(struct ipmi_intf * intf)
{
struct timeval end;
gettimeofday(&end, 0);
if (end.tv_sec - _start_keepalive.tv_sec <= 30)
return 0;
intf->keepalive(intf);
gettimeofday(&_start_keepalive, 0);
return 0;
}
static void
print_escape_seq(struct ipmi_intf *intf)
{
lprintf(LOG_NOTICE,
" %c. - terminate connection\r\n"
" %c^Z - suspend ipmitool\r\n"
" %c^X - suspend ipmitool, but don't restore tty on restart\r\n"
" %c? - this message\r\n"
" %c%c - send the escape character by typing it twice\r\n"
" (Note that escapes are only recognized immediately after newline.)\r",
intf->session->sol_escape_char,
intf->session->sol_escape_char,
intf->session->sol_escape_char,
intf->session->sol_escape_char,
intf->session->sol_escape_char,
intf->session->sol_escape_char);
}
static int
leave_raw_mode(void)
{
if (!_in_raw_mode)
return -1;
else if (tcsetattr(fileno(stdin), TCSADRAIN, &_saved_tio) == -1)
lperror(LOG_ERR, "tcsetattr(stdin)");
else if (tcsetattr(fileno(stdout), TCSADRAIN, &_saved_tio) == -1)
lperror(LOG_ERR, "tcsetattr(stdout)");
else
_in_raw_mode = 0;
return 0;
}
static int
enter_raw_mode(void)
{
struct termios tio;
if (tcgetattr(fileno(stdout), &_saved_tio) < 0) {
lperror(LOG_ERR, "tcgetattr failed");
return -1;
}
tio = _saved_tio;
if (_altterm) {
tio.c_iflag &= (ISTRIP | IGNBRK );
tio.c_cflag &= ~(CSIZE | PARENB | IXON | IXOFF | IXANY);
tio.c_cflag |= (CS8 |CREAD) | (IXON|IXOFF|IXANY);
tio.c_lflag &= 0;
tio.c_cc[VMIN] = 1;
tio.c_cc[VTIME] = 0;
} else {
tio.c_iflag |= IGNPAR;
tio.c_iflag &= ~(ISTRIP | INLCR | IGNCR | ICRNL | IXON | IXANY | IXOFF);
tio.c_lflag &= ~(ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHONL | IEXTEN);
tio.c_oflag &= ~OPOST;
tio.c_cc[VMIN] = 1;
tio.c_cc[VTIME] = 0;
}
if (tcsetattr(fileno(stdin), TCSADRAIN, &tio) < 0)
lperror(LOG_ERR, "tcsetattr(stdin)");
else if (tcsetattr(fileno(stdout), TCSADRAIN, &tio) < 0)
lperror(LOG_ERR, "tcsetattr(stdout)");
else
_in_raw_mode = 1;
return 0;
}
static void
suspend_self(int restore_tty)
{
leave_raw_mode();
kill(getpid(), SIGTSTP);
if (restore_tty)
enter_raw_mode();
}
static int
do_inbuf_actions(struct ipmi_intf *intf, char *in_buff, int len)
{
static int in_esc = 0;
static int last_was_cr = 1;
int i;
for(i = 0; i < len ;) {
if (!in_esc) {
if (last_was_cr &&
(in_buff[i] == intf->session->sol_escape_char)) {
in_esc = 1;
memmove(in_buff, in_buff + 1, len - i - 1);
len--;
continue;
}
}
if (in_esc) {
if (in_buff[i] == intf->session->sol_escape_char) {
in_esc = 0;
i++;
continue;
}
switch (in_buff[i]) {
case '.':
printf("%c. [terminated ipmitool]\r\n",
intf->session->sol_escape_char);
return -1;
case 'Z' - 64:
printf("%c^Z [suspend ipmitool]\r\n",
intf->session->sol_escape_char);
suspend_self(1); /* Restore tty back to raw */
break;
case 'X' - 64:
printf("%c^X [suspend ipmitool]\r\n",
intf->session->sol_escape_char);
suspend_self(0); /* Don't restore to raw mode */
break;
case '?':
printf("%c? [ipmitool help]\r\n",
intf->session->sol_escape_char);
print_escape_seq(intf);
break;
}
memmove(in_buff, in_buff + 1, len - i - 1);
len--;
in_esc = 0;
continue;
}
last_was_cr = (in_buff[i] == '\r' || in_buff[i] == '\n');
i++;
}
return len;
}
static void
do_terminal_cleanup(void)
{
if (_saved_winsize.ws_row > 0 && _saved_winsize.ws_col > 0)
ioctl(fileno(stdout), TIOCSWINSZ, &_saved_winsize);
leave_raw_mode();
if (errno)
lprintf(LOG_ERR, "Exiting due to error %d -> %s",
errno, strerror(errno));
}
static void
set_terminal_size(int rows, int cols)
{
struct winsize winsize;
if (rows <= 0 || cols <= 0)
return;
/* save initial winsize */
ioctl(fileno(stdout), TIOCGWINSZ, &_saved_winsize);
/* set new winsize */
winsize.ws_row = rows;
winsize.ws_col = cols;
ioctl(fileno(stdout), TIOCSWINSZ, &winsize);
}
static void
print_tsol_usage(void)
{
struct winsize winsize;
lprintf(LOG_NOTICE, "Usage: tsol [recvip] [port=NUM] [ro|rw] [rows=NUM] [cols=NUM] [altterm]");
lprintf(LOG_NOTICE, " recvip Receiver IP Address [default=local]");
lprintf(LOG_NOTICE, " port=NUM Receiver UDP Port [default=%d]",
IPMI_TSOL_DEF_PORT);
lprintf(LOG_NOTICE, " ro|rw Set Read-Only or Read-Write [default=rw]");
ioctl(fileno(stdout), TIOCGWINSZ, &winsize);
lprintf(LOG_NOTICE, " rows=NUM Set terminal rows [default=%d]",
winsize.ws_row);
lprintf(LOG_NOTICE, " cols=NUM Set terminal columns [default=%d]",
winsize.ws_col);
lprintf(LOG_NOTICE, " altterm Alternate terminal setup [default=off]");
}
int
ipmi_tsol_main(struct ipmi_intf * intf, int argc, char ** argv)
{
struct pollfd fds_wait[3], fds_data_wait[3], *fds;
struct sockaddr_in sin, myaddr;
socklen_t mylen;
char recvip_c[] = "0.0.0.0";
char *recvip = NULL;
char out_buff[IPMI_BUF_SIZE * 8], in_buff[IPMI_BUF_SIZE];
char buff[IPMI_BUF_SIZE + 4];
int fd_socket, result, i;
int out_buff_fill, in_buff_fill;
int ip1, ip2, ip3, ip4;
int read_only = 0, rows = 0, cols = 0;
int port = IPMI_TSOL_DEF_PORT;
if (strlen(intf->name) == 3 && strncmp(intf->name, "lan", 3) != 0) {
lprintf(LOG_ERR, "Error: Tyan SOL is only available over lan interface");
return -1;
}
for (i = 0; i<argc; i++) {
if (sscanf(argv[i], "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4) == 4)
recvip = strdup(argv[i]);
else if (sscanf(argv[i], "port=%d", &ip1) == 1)
port = ip1;
else if (sscanf(argv[i], "rows=%d", &ip1) == 1)
rows = ip1;
else if (sscanf(argv[i], "cols=%d", &ip1) == 1)
cols = ip1;
else if (strlen(argv[i]) == 2 && strncmp(argv[i], "ro", 2) == 0)
read_only = 1;
else if (strlen(argv[i]) == 2 && strncmp(argv[i], "rw", 2) == 0)
read_only = 0;
else if (strlen(argv[i]) == 7 && strncmp(argv[i], "altterm", 7) == 0)
_altterm = 1;
else if (strlen(argv[i]) == 4 && strncmp(argv[i], "help", 4) == 0) {
print_tsol_usage();
return 0;
}
else {
print_tsol_usage();
return 0;
}
}
/* create udp socket to receive the packet */
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(port);
#ifdef __CYGWIN__
result = inet_aton((const char *)intf->session->hostname,
&intf->session->addr.sin_addr);
#else
result = inet_pton(AF_INET, (const char *)intf->session->hostname,
&intf->session->addr.sin_addr);
#endif
if (result <= 0) {
struct hostent *host = gethostbyname((const char *)intf->session->hostname);
if (host == NULL ) {
lprintf(LOG_ERR, "Address lookup for %s failed",
intf->session->hostname);
return -1;
}
intf->session->addr.sin_family = host->h_addrtype;
memcpy(&intf->session->addr.sin_addr, host->h_addr, host->h_length);
}
fd_socket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (fd_socket < 0) {
lprintf(LOG_ERR, "Can't open port %d", port);
return -1;
}
bind(fd_socket, (struct sockaddr *)&sin, sizeof(sin));
/*
* retrieve local IP address if not supplied on command line
*/
if (recvip == NULL) {
result = intf->open(intf); /* must connect first */
if (result < 0)
return -1;
mylen = sizeof(myaddr);
if (getsockname(intf->fd, (struct sockaddr *)&myaddr, &mylen) < 0) {
lperror(LOG_ERR, "getsockname failed");
return -1;
}
recvip = inet_ntoa(myaddr.sin_addr);
if (recvip == NULL) {
lprintf(LOG_ERR, "Unable to find local IP address");
return -1;
}
}
printf("[Starting %sSOL with receiving address %s:%d]\r\n",
read_only ? "Read-only " : "", recvip, port);
set_terminal_size(rows, cols);
enter_raw_mode();
/*
* talk to smdc to start Console redirect - IP address and port as parameter
* ipmitool -I lan -H 192.168.168.227 -U Administrator raw 0x30 0x06 0xC0 0xA8 0xA8 0x78 0x1A 0x0A
*/
result = ipmi_tsol_start(intf, recvip, port);
if (result < 0) {
lprintf(LOG_ERR, "Error starting SOL");
return -1;
}
printf("[SOL Session operational. Use %c? for help]\r\n",
intf->session->sol_escape_char);
gettimeofday(&_start_keepalive, 0);
fds_wait[0].fd = fd_socket;
fds_wait[0].events = POLLIN;
fds_wait[0].revents = 0;
fds_wait[1].fd = fileno(stdin);
fds_wait[1].events = POLLIN;
fds_wait[1].revents = 0;
fds_wait[2].fd = -1;
fds_wait[2].events = 0;
fds_wait[2].revents = 0;
fds_data_wait[0].fd = fd_socket;
fds_data_wait[0].events = POLLIN | POLLOUT;
fds_data_wait[0].revents = 0;
fds_data_wait[1].fd = fileno(stdin);
fds_data_wait[1].events = POLLIN;
fds_data_wait[1].revents = 0;
fds_data_wait[2].fd = fileno(stdout);
fds_data_wait[2].events = POLLOUT;
fds_data_wait[2].revents = 0;
out_buff_fill = 0;
in_buff_fill = 0;
fds = fds_wait;
for (;;) {
result = poll(fds, 3, 15*1000);
if (result < 0)
break;
/* send keepalive packet */
tsol_keepalive(intf);
if ((fds[0].revents & POLLIN) && (sizeof(out_buff) > out_buff_fill)){
socklen_t sin_len = sizeof(sin);
result = recvfrom(fd_socket, buff, sizeof(out_buff) - out_buff_fill + 4, 0,
(struct sockaddr *)&sin, &sin_len);
/* read the data from udp socket, skip some bytes in the head */
if((result - 4) > 0 ){
int length = result - 4;
#if 1
length = (unsigned char)buff[2] & 0xff;
length *= 256;
length += ((unsigned char)buff[3] & 0xff);
if ((length <= 0) || (length > (result - 4)))
length = result - 4;
#endif
memcpy(out_buff + out_buff_fill, buff + 4, length);
out_buff_fill += length;
}
}
if ((fds[1].revents & POLLIN) && (sizeof(in_buff) > in_buff_fill)) {
result = read(fileno(stdin), in_buff + in_buff_fill,
sizeof(in_buff) - in_buff_fill); // read from keyboard
if (result > 0) {
int bytes;
bytes = do_inbuf_actions(intf, in_buff + in_buff_fill, result);
if(bytes < 0) {
result = ipmi_tsol_stop(intf, recvip, port);
do_terminal_cleanup();
return result;
}
if (read_only)
bytes = 0;
in_buff_fill += bytes;
}
}
if ((fds[2].revents & POLLOUT) && out_buff_fill) {
result = write(fileno(stdout), out_buff, out_buff_fill); // to screen
if (result > 0) {
out_buff_fill -= result;
if (out_buff_fill) {
memmove(out_buff, out_buff + result, out_buff_fill);
}
}
}
if ((fds[0].revents & POLLOUT) && in_buff_fill) {
/*
* translate key and send that to SMDC using IPMI
* ipmitool -I lan -H 192.168.168.227 -U Administrator raw 0x30 0x03 0x04 0x1B 0x5B 0x43
*/
result = ipmi_tsol_send_keystroke(intf, in_buff, __min(in_buff_fill,14));
if (result > 0) {
gettimeofday(&_start_keepalive, 0);
in_buff_fill -= result;
if (in_buff_fill) {
memmove(in_buff, in_buff + result, in_buff_fill);
}
}
}
fds = (in_buff_fill || out_buff_fill )?
fds_data_wait : fds_wait;
}
return 0;
}

View File

@ -142,6 +142,8 @@ ipmi_get_user_name(
struct ipmi_rq req; struct ipmi_rq req;
uint8_t msg_data[1]; uint8_t msg_data[1];
memset(user_name, 0, 17);
memset(&req, 0, sizeof(req)); memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_APP; /* 0x06 */ req.msg.netfn = IPMI_NETFN_APP; /* 0x06 */
req.msg.cmd = IPMI_GET_USER_NAME; /* 0x45 */ req.msg.cmd = IPMI_GET_USER_NAME; /* 0x45 */
@ -158,6 +160,8 @@ ipmi_get_user_name(
return -1; return -1;
} }
if (rsp->ccode > 0) { if (rsp->ccode > 0) {
if (rsp->ccode == 0xcc)
return 0;
lprintf(LOG_ERR, "Get User Name command failed (user %d): %s", lprintf(LOG_ERR, "Get User Name command failed (user %d): %s",
user_id, val2str(rsp->ccode, completion_code_vals)); user_id, val2str(rsp->ccode, completion_code_vals));
return -1; return -1;
@ -259,8 +263,8 @@ ipmi_print_user_list(
++current_user_id; ++current_user_id;
} while((current_user_id < user_access.maximum_ids) && } while((current_user_id <= user_access.maximum_ids) &&
(current_user_id < 63)); /* Absolute maximum allowed by spec */ (current_user_id <= 63)); /* Absolute maximum allowed by spec */
return 0; return 0;
@ -345,6 +349,47 @@ ipmi_user_set_username(
} }
static int
ipmi_user_set_userpriv(
struct ipmi_intf * intf,
uint8_t channel,
uint8_t user_id,
const unsigned char privLevel)
{
struct ipmi_rs * rsp;
struct ipmi_rq req;
uint8_t msg_data[17];
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_APP; /* 0x06 */
req.msg.cmd = IPMI_SET_USER_ACCESS; /* 0x43 */
req.msg.data = msg_data;
req.msg.data_len = 3;
/* The channel number will remain constant throughout this function */
msg_data[0] = (channel & 0x0f); /* Do not change any bytes */
msg_data[1] = (user_id & 0x3f);
msg_data[2] = (privLevel & 0x0f);
rsp = intf->sendrecv(intf, &req);
if (rsp == NULL)
{
lprintf(LOG_ERR, "Set Privilege Level command failed (user %d)",
user_id);
return -1;
}
if (rsp->ccode > 0)
{
lprintf(LOG_ERR, "Set Privilege Level command failed (user %d)",
user_id);
return -1;
}
return 0;
}
/* /*
* ipmi_user_set_password * ipmi_user_set_password
@ -450,15 +495,16 @@ ipmi_user_test_password(
/* /*
* print_user_usage * print_user_usage
*/ */
void static void
print_user_usage() print_user_usage(void)
{ {
lprintf(LOG_NOTICE, "User Commands: summary [<channel number>]"); lprintf(LOG_NOTICE, "User Commands: summary [<channel number>]");
lprintf(LOG_NOTICE, " list [<channel number>]"); lprintf(LOG_NOTICE, " list [<channel number>]");
lprintf(LOG_NOTICE, " set name <user id> <username>"); lprintf(LOG_NOTICE, " set name <user id> <username>");
lprintf(LOG_NOTICE, " set password <user id> [<password>]"); lprintf(LOG_NOTICE, " set password <user id> [<password>]");
lprintf(LOG_NOTICE, " disable <user id> [<channel number>]"); lprintf(LOG_NOTICE, " disable <user id>");
lprintf(LOG_NOTICE, " enable <user id> [<channel number>]"); lprintf(LOG_NOTICE, " enable <user id>");
lprintf(LOG_NOTICE, " priv <user id> <privile level> [<channel number>]");
lprintf(LOG_NOTICE, " test <user id> <16|20> [<password]>\n"); lprintf(LOG_NOTICE, " test <user id> <16|20> [<password]>\n");
} }
@ -484,8 +530,6 @@ ipmi_user_main(struct ipmi_intf * intf, int argc, char ** argv)
{ {
int retval = 0; int retval = 0;
ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN);
/* /*
* Help * Help
*/ */
@ -702,8 +746,40 @@ ipmi_user_main(struct ipmi_intf * intf, int argc, char ** argv)
print_user_usage(); print_user_usage();
return -1; return -1;
} }
} }
else if (strncmp(argv[0], "priv", 4) == 0)
{
uint8_t user_id;
uint8_t priv_level;
uint8_t channel = 0x0e; /* Use channel running on */
if (
(argc != 3) &&
(argc != 4)
)
if (argc == 4)
{
channel = (uint8_t)strtol(argv[3], NULL, 0);
channel = (channel & 0x0f);
}
user_id = (uint8_t)strtol(argv[1], NULL, 0);
priv_level = (uint8_t)strtol(argv[2], NULL, 0);
priv_level = (priv_level & 0x0f);
if (user_id == 0)
{
lprintf(LOG_ERR, "Invalid user ID: %d", user_id);
return -1;
}
retval = ipmi_user_set_userpriv(intf,channel,user_id,priv_level);
}
/* /*
* Disable / Enable * Disable / Enable

View File

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

View File

@ -40,12 +40,8 @@ MAINTAINERCLEANFILES = Makefile.in
ipmitool_SOURCES = ipmitool.c ipmishell.c ipmitool_SOURCES = ipmitool.c ipmishell.c
ipmitool_LDADD = $(top_builddir)/lib/libipmitool.la plugins/libintf.la ipmitool_LDADD = $(top_builddir)/lib/libipmitool.la plugins/libintf.la
if IPMIEVD
ipmievd_SOURCES = ipmievd.c ipmievd_SOURCES = ipmievd.c
ipmievd_LDADD = $(top_builddir)/lib/libipmitool.la plugins/libintf.la ipmievd_LDADD = $(top_builddir)/lib/libipmitool.la plugins/libintf.la
endif
EXTRA_DIST = ipmievd.c bin_PROGRAMS = ipmitool
sbin_PROGRAMS = ipmievd
bin_PROGRAMS = ipmitool @IPMIEVD_BIN@
EXTRA_PROGRAMS = ipmitool ipmievd

View File

@ -44,7 +44,6 @@
#include <string.h> #include <string.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/poll.h>
#ifdef __FreeBSD__ #ifdef __FreeBSD__
# include <signal.h> # include <signal.h>
@ -53,85 +52,250 @@
#include <config.h> #include <config.h>
#ifdef IPMI_INTF_OPEN
# ifdef HAVE_OPENIPMI_H # ifdef HAVE_OPENIPMI_H
# include <linux/compiler.h>
# include <linux/ipmi.h> # include <linux/ipmi.h>
#else # include <sys/poll.h>
# else /* HAVE_OPENIPMI_H */
# include "plugins/open/open.h" # include "plugins/open/open.h"
#endif # include <sys/poll.h>
# endif /* HAVE_OPENIPMI_H */
#endif /* IPMI_INTF_OPEN */
#include <ipmitool/helper.h> #include <ipmitool/helper.h>
#include <ipmitool/log.h> #include <ipmitool/log.h>
#include <ipmitool/ipmi.h> #include <ipmitool/ipmi.h>
#include <ipmitool/ipmi_intf.h> #include <ipmitool/ipmi_intf.h>
#include <ipmitool/ipmi_sel.h> #include <ipmitool/ipmi_sel.h>
#include <ipmitool/ipmi_sdr.h>
#include <ipmitool/ipmi_strings.h>
#include <ipmitool/ipmi_main.h>
extern int errno; /* global variables */
int verbose = 0; int verbose = 0;
int csv_output = 0; int csv_output = 0;
uint16_t selwatch_count = 0; /* number of entries in the SEL */
uint16_t selwatch_lastid = 0; /* current last entry in the SEL */
int selwatch_timeout = 10; /* default to 10 seconds */
static void daemonize(void) /* event interface definition */
{ struct ipmi_event_intf {
pid_t pid; char name[16];
int fd; char desc[128];
#ifdef SIGHUP int (*setup)(struct ipmi_event_intf * eintf);
sigset_t sighup; int (*wait)(struct ipmi_event_intf * eintf);
int (*read)(struct ipmi_event_intf * eintf);
int (*check)(struct ipmi_event_intf * eintf);
void (*log)(struct ipmi_event_intf * eintf, struct sel_event_record * evt);
struct ipmi_intf * intf;
};
static void log_event(struct ipmi_event_intf * eintf, struct sel_event_record * evt);
/* ~~~~~~~~~~~~~~~~~~~~~~ openipmi ~~~~~~~~~~~~~~~~~~~~ */
#ifdef IPMI_INTF_OPEN
static int openipmi_setup(struct ipmi_event_intf * eintf);
static int openipmi_wait(struct ipmi_event_intf * eintf);
static int openipmi_read(struct ipmi_event_intf * eintf);
static struct ipmi_event_intf openipmi_event_intf = {
name: "open",
desc: "OpenIPMI asyncronous notification of events",
setup: openipmi_setup,
wait: openipmi_wait,
read: openipmi_read,
log: log_event,
};
#endif #endif
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
/* if we are started from init no need to become daemon */ /* ~~~~~~~~~~~~~~~~~~~~~~ selwatch ~~~~~~~~~~~~~~~~~~~~ */
if (getppid() == 1) static int selwatch_setup(struct ipmi_event_intf * eintf);
static int selwatch_wait(struct ipmi_event_intf * eintf);
static int selwatch_read(struct ipmi_event_intf * eintf);
static int selwatch_check(struct ipmi_event_intf * eintf);
static struct ipmi_event_intf selwatch_event_intf = {
name: "sel",
desc: "Poll SEL for notification of events",
setup: selwatch_setup,
wait: selwatch_wait,
read: selwatch_read,
check: selwatch_check,
log: log_event,
};
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
struct ipmi_event_intf * ipmi_event_intf_table[] = {
#ifdef IPMI_INTF_OPEN
&openipmi_event_intf,
#endif
&selwatch_event_intf,
NULL
};
/*************************************************************************/
static void
ipmievd_usage(void)
{
lprintf(LOG_NOTICE, "Options:");
lprintf(LOG_NOTICE, "\ttimeout=# Time between checks for SEL polling method [default=10]");
lprintf(LOG_NOTICE, "\tdaemon Become a daemon [default]");
lprintf(LOG_NOTICE, "\tnodaemon Do NOT become a daemon");
}
/* ipmi_intf_load - Load an event interface from the table above
* If no interface name is given return first entry
*
* @name: interface name to try and load
*
* returns pointer to inteface structure if found
* returns NULL on error
*/
static struct ipmi_event_intf *
ipmi_event_intf_load(char * name)
{
struct ipmi_event_intf ** intf;
struct ipmi_event_intf * i;
if (name == NULL) {
i = ipmi_event_intf_table[0];
return i;
}
for (intf = ipmi_event_intf_table;
((intf != NULL) && (*intf != NULL));
intf++) {
i = *intf;
if (strncmp(name, i->name, strlen(name)) == 0) {
return i;
}
}
return NULL;
}
static void
log_event(struct ipmi_event_intf * eintf, struct sel_event_record * evt)
{
char *desc;
const char *type;
struct sdr_record_list * sdr;
struct ipmi_intf * intf = eintf->intf;
float trigger_reading = 0.0;
float threshold_reading = 0.0;
if (evt == NULL)
return; return;
#ifdef SIGHUP if (evt->record_type == 0xf0) {
sigemptyset(&sighup); lprintf(LOG_ALERT, "Linux kernel panic: %.11s", (char *) evt + 5);
sigaddset(&sighup, SIGHUP); return;
if (sigprocmask(SIG_UNBLOCK, &sighup, NULL) < 0)
fprintf(stderr, "ERROR: could not unblock SIGHUP signal\n");
signal(SIGHUP, SIG_IGN);
#endif
#ifdef SIGTTOU
signal(SIGTTOU, SIG_IGN);
#endif
#ifdef SIGTTIN
signal(SIGTTIN, SIG_IGN);
#endif
#ifdef SIGQUIT
signal(SIGQUIT, SIG_IGN);
#endif
#ifdef SIGTSTP
signal(SIGTSTP, SIG_IGN);
#endif
pid = (pid_t) fork();
if (pid < 0 || pid > 0)
exit(0);
#if defined(SIGTSTP) && defined(TIOCNOTTY)
if (setpgid(0, getpid()) == -1)
exit(1);
if ((fd = open(_PATH_TTY, O_RDWR)) >= 0) {
ioctl(fd, TIOCNOTTY, NULL);
close(fd);
} }
#else else if (evt->record_type >= 0xc0) {
if (setpgrp() == -1) lprintf(LOG_NOTICE, "IPMI Event OEM Record %02x", evt->record_type);
exit(1); return;
pid = (pid_t) fork();
if (pid < 0 || pid > 0)
exit(0);
#endif
chdir("/");
umask(0);
for (fd=0; fd<64; fd++)
close(fd);
open("/dev/null", O_RDWR);
dup(0);
dup(0);
} }
static int enable_event_msg_buffer(struct ipmi_intf * intf) type = ipmi_sel_get_sensor_type_offset(evt->sel_type.standard_type.sensor_type, evt->sel_type.standard_type.event_data[0]);
ipmi_get_event_desc(intf, evt, &desc);
sdr = ipmi_sdr_find_sdr_bynumtype(intf, evt->sel_type.standard_type.sensor_num, evt->sel_type.standard_type.sensor_type);
if (sdr == NULL) {
/* could not find matching SDR record */
if (desc) {
lprintf(LOG_NOTICE, "%s sensor - %s",
type, desc);
free(desc);
} else {
lprintf(LOG_NOTICE, "%s sensor %02x",
type, evt->sel_type.standard_type.sensor_num);
}
return;
}
switch (sdr->type) {
case SDR_RECORD_TYPE_FULL_SENSOR:
if (evt->sel_type.standard_type.event_type == 1) {
/*
* Threshold Event
*/
/* trigger reading in event data byte 2 */
if (((evt->sel_type.standard_type.event_data[0] >> 6) & 3) == 1) {
trigger_reading = sdr_convert_sensor_reading(
sdr->record.full, evt->sel_type.standard_type.event_data[1]);
}
/* trigger threshold in event data byte 3 */
if (((evt->sel_type.standard_type.event_data[0] >> 4) & 3) == 1) {
threshold_reading = sdr_convert_sensor_reading(
sdr->record.full, evt->sel_type.standard_type.event_data[2]);
}
lprintf(LOG_NOTICE, "%s sensor %s %s (Reading %.*f %s Threshold %.*f %s)",
type,
sdr->record.full->id_string,
desc ? : "",
(trigger_reading==(int)trigger_reading) ? 0 : 2,
trigger_reading,
((evt->sel_type.standard_type.event_data[0] & 0xf) % 2) ? ">" : "<",
(threshold_reading==(int)threshold_reading) ? 0 : 2,
threshold_reading,
ipmi_sdr_get_unit_string(sdr->record.full->unit.modifier,
sdr->record.full->unit.type.base,
sdr->record.full->unit.type.modifier));
}
else if ((evt->sel_type.standard_type.event_type >= 0x2 && evt->sel_type.standard_type.event_type <= 0xc) ||
(evt->sel_type.standard_type.event_type == 0x6f)) {
/*
* Discrete Event
*/
lprintf(LOG_NOTICE, "%s sensor %s %s",
type, sdr->record.full->id_string, desc ? : "");
if (((evt->sel_type.standard_type.event_data[0] >> 6) & 3) == 1) {
/* previous state and/or severity in event data byte 2 */
}
}
else if (evt->sel_type.standard_type.event_type >= 0x70 && evt->sel_type.standard_type.event_type <= 0x7f) {
/*
* OEM Event
*/
lprintf(LOG_NOTICE, "%s sensor %s %s",
type, sdr->record.full->id_string, desc ? : "");
}
break;
case SDR_RECORD_TYPE_COMPACT_SENSOR:
if (evt->sel_type.standard_type.event_type == 0x6f) {
lprintf(LOG_NOTICE, "%s sensor %s - %s %s",
type, sdr->record.compact->id_string,
desc ? : "",
evt->sel_type.standard_type.event_dir ? "Deasserted" : "Asserted");
} else {
lprintf(LOG_NOTICE, "%s sensor %s - %s",
type, sdr->record.compact->id_string, desc ? : "");
}
break;
default:
lprintf(LOG_NOTICE, "%s sensor - %s",
type, evt->sel_type.standard_type.sensor_num, desc ? : "");
break;
}
if (desc)
free(desc);
}
/*************************************************************************/
/*************************************************************************/
/** OpenIPMI Functions **/
/*************************************************************************/
#ifdef IPMI_INTF_OPEN
static int
openipmi_enable_event_msg_buffer(struct ipmi_intf * intf)
{ {
struct ipmi_rs * rsp; struct ipmi_rs * rsp;
struct ipmi_rq req; struct ipmi_rq req;
@ -143,9 +307,13 @@ static int enable_event_msg_buffer(struct ipmi_intf * intf)
req.msg.cmd = 0x2f; /* Get BMC Global Enables */ req.msg.cmd = 0x2f; /* Get BMC Global Enables */
rsp = intf->sendrecv(intf, &req); rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode) { if (rsp == NULL) {
lprintf(LOG_WARNING, "Get BMC Global Enables command filed [ccode %02x]", lprintf(LOG_ERR, "Get BMC Global Enables command failed");
rsp ? rsp->ccode : 0); return -1;
}
else if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Get BMC Global Enables command failed: %s",
val2str(rsp->ccode, completion_code_vals));
return -1; return -1;
} }
@ -155,9 +323,13 @@ static int enable_event_msg_buffer(struct ipmi_intf * intf)
req.msg.data_len = 1; req.msg.data_len = 1;
rsp = intf->sendrecv(intf, &req); rsp = intf->sendrecv(intf, &req);
if (!rsp || rsp->ccode) { if (rsp == NULL) {
lprintf(LOG_WARNING, "Set BMC Global Enables command failed [ccode %02x]", lprintf(LOG_ERR, "Set BMC Global Enables command failed");
rsp ? rsp->ccode : 0); return -1;
}
else if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Set BMC Global Enables command failed: %s",
val2str(rsp->ccode, completion_code_vals));
return -1; return -1;
} }
@ -166,29 +338,33 @@ static int enable_event_msg_buffer(struct ipmi_intf * intf)
return 0; return 0;
} }
static void log_event(struct sel_event_record * evt) static int
openipmi_setup(struct ipmi_event_intf * eintf)
{ {
char *desc; int i, r;
if (!evt) /* enable event message buffer */
return; lprintf(LOG_DEBUG, "Enabling event message buffer");
r = openipmi_enable_event_msg_buffer(eintf->intf);
if (evt->record_type == 0xf0) if (r < 0) {
lprintf(LOG_ALERT, "Linux kernel panic: %.11s", (char *) evt + 5); lprintf(LOG_ERR, "Could not enable event message buffer");
else if (evt->record_type >= 0xc0) return -1;
lprintf(LOG_NOTICE, "IPMI Event OEM Record %02x", evt->record_type);
else {
ipmi_get_event_desc(evt, &desc);
if (desc) {
lprintf(LOG_NOTICE, "%s Sensor %02x - %s",
ipmi_sel_get_sensor_type(evt->sensor_type),
evt->sensor_num, desc);
free(desc);
}
}
} }
static void read_event(struct ipmi_intf * intf) /* enable OpenIPMI event receiver */
lprintf(LOG_DEBUG, "Enabling event receiver");
i = 1;
r = ioctl(eintf->intf->fd, IPMICTL_SET_GETS_EVENTS_CMD, &i);
if (r != 0) {
lperror(LOG_ERR, "Could not enable event receiver");
return -1;
}
return 0;
}
static int
openipmi_read(struct ipmi_event_intf * eintf)
{ {
struct ipmi_addr addr; struct ipmi_addr addr;
struct ipmi_recv recv; struct ipmi_recv recv;
@ -200,126 +376,45 @@ static void read_event(struct ipmi_intf * intf)
recv.msg.data = data; recv.msg.data = data;
recv.msg.data_len = sizeof(data); recv.msg.data_len = sizeof(data);
rv = ioctl(intf->fd, IPMICTL_RECEIVE_MSG_TRUNC, &recv); rv = ioctl(eintf->intf->fd, IPMICTL_RECEIVE_MSG_TRUNC, &recv);
if (rv < 0) { if (rv < 0) {
switch (errno) { switch (errno) {
case EINTR: case EINTR:
return; /* abort */ return 0; /* abort */
case EMSGSIZE: case EMSGSIZE:
recv.msg.data_len = sizeof(data); /* truncated */ recv.msg.data_len = sizeof(data); /* truncated */
break; break;
default: default:
lperror(LOG_ERR, "Unable to receive IPMI message"); lperror(LOG_ERR, "Unable to receive IPMI message");
return; return -1;
} }
} }
if (!recv.msg.data || recv.msg.data_len == 0) { if (!recv.msg.data || recv.msg.data_len == 0) {
lprintf(LOG_ERR, "No data in event"); lprintf(LOG_ERR, "No data in event");
return; return -1;
} }
if (recv.recv_type != IPMI_ASYNC_EVENT_RECV_TYPE) { if (recv.recv_type != IPMI_ASYNC_EVENT_RECV_TYPE) {
lprintf(LOG_ERR, "Type %x is not an event", recv.recv_type); lprintf(LOG_ERR, "Type %x is not an event", recv.recv_type);
return; return -1;
} }
lprintf(LOG_DEBUG, "netfn:%x cmd:%x ccode:%d", lprintf(LOG_DEBUG, "netfn:%x cmd:%x ccode:%d",
recv.msg.netfn, recv.msg.cmd, recv.msg.data[0]); recv.msg.netfn, recv.msg.cmd, recv.msg.data[0]);
log_event((struct sel_event_record *)recv.msg.data); eintf->log(eintf, (struct sel_event_record *)recv.msg.data);
return 0;
} }
static int do_exit(struct ipmi_intf * intf, int rv) static int
openipmi_wait(struct ipmi_event_intf * eintf)
{ {
if (intf)
intf->close(intf);
log_halt();
exit(rv);
}
static void usage(void)
{
fprintf(stderr, "usage: ipmievd [-hvd]\n");
fprintf(stderr, "\n");
fprintf(stderr, " -h This help\n");
fprintf(stderr, " -v Verbose (can use multiple times)\n");
fprintf(stderr, " -s Do NOT daemonize\n");
fprintf(stderr, "\n");
}
int main(int argc, char ** argv)
{
struct ipmi_intf * intf;
int r, a;
int i = 1;
int daemon = 1;
struct pollfd pfd; struct pollfd pfd;
int r;
/* make sure we have UID 0 */
if (geteuid() || getuid()) {
fprintf(stderr, "Inadequate privledges\n");
do_exit(NULL, EXIT_FAILURE);
}
while ((a = getopt(argc, (char **)argv, "hvs")) != -1) {
switch (a) {
case 'h':
usage();
do_exit(NULL, EXIT_SUCCESS);
break;
case 'v':
verbose++;
break;
case 's':
daemon = 0;
break;
default:
usage();
do_exit(NULL, EXIT_FAILURE);
}
}
if (daemon)
daemonize();
log_init("ipmievd", daemon, verbose);
/* load interface */
lprintf(LOG_DEBUG, "Loading OpenIPMI interface");
intf = ipmi_intf_load("open");
if (!intf) {
lprintf(LOG_ERR, "Unable to load OpenIPMI interface");
do_exit(NULL, EXIT_FAILURE);
}
/* open connection to openipmi device */
lprintf(LOG_DEBUG, "Connecting to OpenIPMI device");
r = intf->open(intf);
if (r < 0) {
lprintf(LOG_ERR, "Unable to open OpenIPMI device");
do_exit(NULL, EXIT_FAILURE);
}
/* enable event message buffer */
lprintf(LOG_DEBUG, "Enabling event message buffer");
r = enable_event_msg_buffer(intf);
if (r < 0) {
lprintf(LOG_ERR, "Could not enable event message buffer");
do_exit(intf, EXIT_FAILURE);
}
/* enable OpenIPMI event receiver */
lprintf(LOG_DEBUG, "Enabling event receiver");
r = ioctl(intf->fd, IPMICTL_SET_GETS_EVENTS_CMD, &i);
if (r != 0) {
lperror(LOG_ERR, "Could not enable event receiver");
do_exit(intf, EXIT_FAILURE);
}
lprintf(LOG_NOTICE, "Waiting for events...");
for (;;) { for (;;) {
pfd.fd = intf->fd; /* wait on openipmi device */ pfd.fd = eintf->intf->fd; /* wait on openipmi device */
pfd.events = POLLIN; /* wait for input */ pfd.events = POLLIN; /* wait for input */
r = poll(&pfd, 1, -1); r = poll(&pfd, 1, -1);
@ -329,14 +424,284 @@ int main(int argc, char ** argv)
break; break;
case -1: case -1:
lperror(LOG_CRIT, "Unable to read from IPMI device"); lperror(LOG_CRIT, "Unable to read from IPMI device");
do_exit(intf, EXIT_FAILURE); return -1;
break;
default: default:
if (pfd.revents && POLLIN) if (pfd.revents & POLLIN)
read_event(intf); eintf->read(eintf);
} }
} }
lprintf(LOG_DEBUG, "Shutting down..."); return 0;
do_exit(intf, EXIT_SUCCESS); }
#endif /* IPMI_INTF_OPEN */
/*************************************************************************/
/*************************************************************************/
/** SEL Watch Functions **/
/*************************************************************************/
static uint16_t
selwatch_get_count(struct ipmi_intf * intf)
{
struct ipmi_rs * rsp;
struct ipmi_rq req;
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_STORAGE;
req.msg.cmd = IPMI_CMD_GET_SEL_INFO;
rsp = intf->sendrecv(intf, &req);
if (rsp == NULL) {
lprintf(LOG_ERR, "Get SEL Info command failed");
return 0;
}
if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Get SEL Info command failed: %s",
val2str(rsp->ccode, completion_code_vals));
return 0;
}
lprintf(LOG_DEBUG, "SEL count is %d", buf2short(rsp->data+1));
return buf2short(rsp->data+1);
}
static uint16_t
selwatch_get_lastid(struct ipmi_intf * intf)
{
int next_id = 0;
uint16_t curr_id = 0;
struct sel_event_record evt;
if (selwatch_count == 0)
return 0;
while (next_id != 0xffff) {
curr_id = next_id;
lprintf(LOG_DEBUG, "SEL Next ID: %04x", curr_id);
next_id = ipmi_sel_get_std_entry(intf, curr_id, &evt);
if (next_id < 0)
break;
if (next_id == 0) {
/*
* usually next_id of zero means end but
* retry because some hardware has quirks
* and will return 0 randomly.
*/
next_id = ipmi_sel_get_std_entry(intf, curr_id, &evt);
if (next_id <= 0)
break;
}
}
lprintf(LOG_DEBUG, "SEL lastid is %04x", curr_id);
return curr_id;
}
static int
selwatch_setup(struct ipmi_event_intf * eintf)
{
/* save current sel record count */
selwatch_count = selwatch_get_count(eintf->intf);
lprintf(LOG_DEBUG, "Current SEL count is %d", selwatch_count);
/* save current last record ID */
selwatch_lastid = selwatch_get_lastid(eintf->intf);
lprintf(LOG_DEBUG, "Current SEL lastid is %04x", selwatch_lastid);
return 0;
}
/* selwatch_check - check for waiting events
*
* this is done by reading sel info and comparing
* the sel count value to what we currently know
*/
static int
selwatch_check(struct ipmi_event_intf * eintf)
{
uint16_t old_count = selwatch_count;
selwatch_count = selwatch_get_count(eintf->intf);
if (selwatch_count == 0) {
lprintf(LOG_DEBUG, "SEL count is 0 (old=%d), resetting lastid to 0", old_count);
selwatch_lastid = 0;
} else if (selwatch_count < old_count) {
selwatch_lastid = selwatch_get_lastid(eintf->intf);
lprintf(LOG_DEBUG, "SEL count lowered, new SEL lastid is %04x", selwatch_lastid);
}
return (selwatch_count > old_count);
}
static int
selwatch_read(struct ipmi_event_intf * eintf)
{
uint16_t curr_id = 0;
int next_id = selwatch_lastid;
struct sel_event_record evt;
if (selwatch_count == 0)
return -1;
while (next_id != 0xffff) {
curr_id = next_id;
lprintf(LOG_DEBUG, "SEL Read ID: %04x", curr_id);
next_id = ipmi_sel_get_std_entry(eintf->intf, curr_id, &evt);
if (next_id < 0)
break;
if (next_id == 0) {
/*
* usually next_id of zero means end but
* retry because some hardware has quirks
* and will return 0 randomly.
*/
next_id = ipmi_sel_get_std_entry(eintf->intf, curr_id, &evt);
if (next_id <= 0)
break;
}
if (curr_id != selwatch_lastid)
eintf->log(eintf, &evt);
else if (curr_id == 0)
eintf->log(eintf, &evt);
}
selwatch_lastid = curr_id;
return 0;
}
static int
selwatch_wait(struct ipmi_event_intf * eintf)
{
for (;;) {
if (eintf->check(eintf) > 0) {
lprintf(LOG_DEBUG, "New Events");
eintf->read(eintf);
}
sleep(selwatch_timeout);
}
}
/*************************************************************************/
int
ipmievd_main(struct ipmi_event_intf * eintf, int argc, char ** argv)
{
int i, rc;
int daemon = 1;
for (i = 0; i < argc; i++) {
if (strncasecmp(argv[i], "help", 4) == 0) {
ipmievd_usage();
return 0;
}
if (strncasecmp(argv[i], "daemon", 6) == 0) {
daemon = 1;
}
else if (strncasecmp(argv[i], "nodaemon", 8) == 0) {
daemon = 0;
}
else if (strncasecmp(argv[i], "daemon=", 7) == 0) {
if (strncasecmp(argv[i]+7, "on", 2) == 0 ||
strncasecmp(argv[i]+7, "yes", 3) == 0)
daemon = 1;
else if (strncasecmp(argv[i]+7, "off", 3) == 0 ||
strncasecmp(argv[i]+7, "no", 2) == 0)
daemon = 0;
}
else if (strncasecmp(argv[i], "timeout=", 8) == 0) {
selwatch_timeout = strtoul(argv[i]+8, NULL, 0);
}
}
if (daemon)
ipmi_start_daemon();
log_halt();
log_init("ipmievd", daemon, verbose);
/* generate SDR cache for fast lookups */
lprintf(LOG_NOTICE, "Reading sensors...");
ipmi_sdr_list_cache(eintf->intf);
lprintf(LOG_DEBUG, "Sensors cached");
/* call event handler setup routine */
if (eintf->setup != NULL) {
rc = eintf->setup(eintf);
if (rc < 0) {
lprintf(LOG_ERR, "Error setting up Event Interface %s", eintf->name);
return -1;
}
}
lprintf(LOG_NOTICE, "Waiting for events...");
/* now launch event wait loop */
if (eintf->wait != NULL) {
rc = eintf->wait(eintf);
if (rc < 0) {
lprintf(LOG_ERR, "Error waiting for events!");
return -1;
}
}
return 0;
}
int
ipmievd_sel_main(struct ipmi_intf * intf, int argc, char ** argv)
{
struct ipmi_event_intf * eintf;
eintf = ipmi_event_intf_load("sel");
if (eintf == NULL) {
lprintf(LOG_ERR, "Unable to load event interface");
return -1;
}
eintf->intf = intf;
return ipmievd_main(eintf, argc, argv);
}
int
ipmievd_open_main(struct ipmi_intf * intf, int argc, char ** argv)
{
struct ipmi_event_intf * eintf;
/* only one interface works for this */
if (strncmp(intf->name, "open", 4) != 0) {
lprintf(LOG_ERR, "Invalid Interface for OpenIPMI Event Handler: %s", intf->name);
return -1;
}
eintf = ipmi_event_intf_load("open");
if (eintf == NULL) {
lprintf(LOG_ERR, "Unable to load event interface");
return -1;
}
eintf->intf = intf;
return ipmievd_main(eintf, argc, argv);
}
struct ipmi_cmd ipmievd_cmd_list[] = {
#ifdef IPMI_INTF_OPEN
{ ipmievd_open_main, "open", "Use OpenIPMI for asyncronous notification of events" },
#endif
{ ipmievd_sel_main, "sel", "Poll SEL for notification of events" },
{ NULL }
};
int main(int argc, char ** argv)
{
int rc;
rc = ipmi_main(argc, argv, ipmievd_cmd_list, NULL);
if (rc < 0)
exit(EXIT_FAILURE);
else
exit(EXIT_SUCCESS);
} }

View File

@ -46,6 +46,7 @@
#include <ipmitool/ipmi.h> #include <ipmitool/ipmi.h>
#include <ipmitool/ipmi_intf.h> #include <ipmitool/ipmi_intf.h>
#include <ipmitool/ipmi_session.h> #include <ipmitool/ipmi_session.h>
#include <ipmitool/ipmi_main.h>
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> # include <config.h>
@ -54,9 +55,6 @@
#define EXEC_BUF_SIZE 1024 #define EXEC_BUF_SIZE 1024
#define EXEC_ARG_SIZE 32 #define EXEC_ARG_SIZE 32
extern void ipmi_cmd_print(void);
extern int ipmi_cmd_run(struct ipmi_intf * intf, char * name, int argc, char ** argv);
extern const struct valstr ipmi_privlvl_vals[]; extern const struct valstr ipmi_privlvl_vals[];
extern const struct valstr ipmi_authtype_session_vals[]; extern const struct valstr ipmi_authtype_session_vals[];
@ -98,7 +96,7 @@ static int rl_event_keepalive(void)
int ipmi_shell_main(struct ipmi_intf * intf, int argc, char ** argv) int ipmi_shell_main(struct ipmi_intf * intf, int argc, char ** argv)
{ {
char *pbuf, **ap, *__argv[20]; char *ptr, *pbuf, **ap, *__argv[20];
int __argc, rc=0; int __argc, rc=0;
rl_readline_name = "ipmitool"; rl_readline_name = "ipmitool";
@ -113,8 +111,9 @@ int ipmi_shell_main(struct ipmi_intf * intf, int argc, char ** argv)
shell_intf = intf; shell_intf = intf;
rl_event_hook = rl_event_keepalive; rl_event_hook = rl_event_keepalive;
#if defined(RL_READLINE_VERSION) && RL_READLINE_VERSION >= 0x0402 #if defined(RL_READLINE_VERSION) && RL_READLINE_VERSION >= 0x0402
/* set to 1 second */ /* There is a bug in readline 4.2 and later (at least on FreeBSD):
rl_set_keyboard_input_timeout(1000*1000); * timeout equal or greater than 1 second causes an infinite loop. */
rl_set_keyboard_input_timeout(1000 * 1000 - 1);
#endif #endif
} }
@ -130,7 +129,7 @@ int ipmi_shell_main(struct ipmi_intf * intf, int argc, char ** argv)
} }
if (strncmp(pbuf, "help", 4) == 0 || if (strncmp(pbuf, "help", 4) == 0 ||
strncmp(pbuf, "?", 1) == 0) { strncmp(pbuf, "?", 1) == 0) {
ipmi_cmd_print(); ipmi_cmd_print(intf->cmdlist);
free(pbuf); free(pbuf);
continue; continue;
} }
@ -138,6 +137,28 @@ int ipmi_shell_main(struct ipmi_intf * intf, int argc, char ** argv)
/* for the all-important up arrow :) */ /* for the all-important up arrow :) */
add_history(pbuf); add_history(pbuf);
/* change "" and '' with spaces in the middle to ~ */
ptr = pbuf;
while (*ptr != '\0') {
if (*ptr == '"') {
ptr++;
while (*ptr != '"') {
if (isspace(*ptr))
*ptr = '~';
ptr++;
}
}
if (*ptr == '\'') {
ptr++;
while (*ptr != '\'') {
if (isspace(*ptr))
*ptr = '~';
ptr++;
}
}
ptr++;
}
__argc = 0; __argc = 0;
ap = __argv; ap = __argv;
@ -145,6 +166,27 @@ int ipmi_shell_main(struct ipmi_intf * intf, int argc, char ** argv)
*ap != NULL; *ap != NULL;
*ap = strtok(NULL, " \t")) { *ap = strtok(NULL, " \t")) {
__argc++; __argc++;
ptr = *ap;
if (*ptr == '\'') {
memmove(ptr, ptr+1, strlen(ptr));
while (*ptr != '\'') {
if (*ptr == '~')
*ptr = ' ';
ptr++;
}
*ptr = '\0';
}
if (*ptr == '"') {
memmove(ptr, ptr+1, strlen(ptr));
while (*ptr != '"') {
if (*ptr == '~')
*ptr = ' ';
ptr++;
}
*ptr = '\0';
}
if (**ap != '\0') { if (**ap != '\0') {
if (++ap >= &__argv[20]) if (++ap >= &__argv[20])
break; break;
@ -173,6 +215,16 @@ ipmi_shell_main(struct ipmi_intf * intf, int argc, char ** argv)
#endif /* HAVE_READLINE */ #endif /* HAVE_READLINE */
int ipmi_echo_main(struct ipmi_intf * intf, int argc, char ** argv)
{
int i;
for (i=0; i<argc; i++) {
printf("%s ", argv[i]);
}
printf("\n");
}
static void static void
ipmi_set_usage(void) ipmi_set_usage(void)
{ {
@ -230,19 +282,27 @@ int ipmi_set_main(struct ipmi_intf * intf, int argc, char ** argv)
printf("Set session password\n"); printf("Set session password\n");
} }
else if (strncmp(argv[0], "authtype", 8) == 0) { else if (strncmp(argv[0], "authtype", 8) == 0) {
uint8_t authtype; int authtype;
authtype = (uint8_t)str2val(argv[1], ipmi_authtype_session_vals); authtype = str2val(argv[1], ipmi_authtype_session_vals);
if (authtype == 0xFF) {
lprintf(LOG_ERR, "Invalid authtype: %s", argv[1]);
} else {
ipmi_intf_session_set_authtype(intf, authtype); ipmi_intf_session_set_authtype(intf, authtype);
printf("Set session authtype to %s\n", printf("Set session authtype to %s\n",
val2str(intf->session->authtype_set, ipmi_authtype_session_vals)); val2str(intf->session->authtype_set, ipmi_authtype_session_vals));
} }
}
else if (strncmp(argv[0], "privlvl", 7) == 0) { else if (strncmp(argv[0], "privlvl", 7) == 0) {
uint8_t privlvl; int privlvl;
privlvl = (uint8_t)str2val(argv[1], ipmi_privlvl_vals); privlvl = str2val(argv[1], ipmi_privlvl_vals);
if (privlvl == 0xFF) {
lprintf(LOG_ERR, "Invalid privilege level: %s", argv[1]);
} else {
ipmi_intf_session_set_privlvl(intf, privlvl); ipmi_intf_session_set_privlvl(intf, privlvl);
printf("Set session privilege level to %s\n", printf("Set session privilege level to %s\n",
val2str(intf->session->privlvl, ipmi_privlvl_vals)); val2str(intf->session->privlvl, ipmi_privlvl_vals));
} }
}
else if (strncmp(argv[0], "port", 4) == 0) { else if (strncmp(argv[0], "port", 4) == 0) {
int port = atoi(argv[1]); int port = atoi(argv[1]);
ipmi_intf_session_set_port(intf, port); ipmi_intf_session_set_port(intf, port);
@ -267,7 +327,7 @@ int ipmi_exec_main(struct ipmi_intf * intf, int argc, char ** argv)
{ {
FILE * fp; FILE * fp;
char buf[EXEC_BUF_SIZE]; char buf[EXEC_BUF_SIZE];
char * ptr, * tok, * ret; char * ptr, * tok, * ret, * tmp;
int __argc, i, r; int __argc, i, r;
char * __argv[EXEC_ARG_SIZE]; char * __argv[EXEC_ARG_SIZE];
int rc=0; int rc=0;
@ -293,6 +353,28 @@ int ipmi_exec_main(struct ipmi_intf * intf, int argc, char ** argv)
else else
ptr = buf + strlen(buf); ptr = buf + strlen(buf);
/* change "" and '' with spaces in the middle to ~ */
ptr = buf;
while (*ptr != '\0') {
if (*ptr == '"') {
ptr++;
while (*ptr != '"') {
if (isspace(*ptr))
*ptr = '~';
ptr++;
}
}
if (*ptr == '\'') {
ptr++;
while (*ptr != '\'') {
if (isspace(*ptr))
*ptr = '~';
ptr++;
}
}
ptr++;
}
/* clip off trailing and leading whitespace */ /* clip off trailing and leading whitespace */
ptr--; ptr--;
while (isspace(*ptr) && ptr >= buf) while (isspace(*ptr) && ptr >= buf)
@ -305,16 +387,33 @@ int ipmi_exec_main(struct ipmi_intf * intf, int argc, char ** argv)
/* parse it and make argument list */ /* parse it and make argument list */
__argc = 0; __argc = 0;
tok = strtok(ptr, " "); for (tok = strtok(ptr, " "); tok != NULL; tok = strtok(NULL, " ")) {
while (tok) {
if (__argc < EXEC_ARG_SIZE) { if (__argc < EXEC_ARG_SIZE) {
__argv[__argc++] = strdup(tok); __argv[__argc++] = strdup(tok);
if (__argv[__argc-1] == NULL) { if (__argv[__argc-1] == NULL) {
lprintf(LOG_ERR, "ipmitool: malloc failure"); lprintf(LOG_ERR, "ipmitool: malloc failure");
return -1; return -1;
} }
tmp = __argv[__argc-1];
if (*tmp == '\'') {
memmove(tmp, tmp+1, strlen(tmp));
while (*tmp != '\'') {
if (*tmp == '~')
*tmp = ' ';
tmp++;
}
*tmp = '\0';
}
if (*tmp == '"') {
memmove(tmp, tmp+1, strlen(tmp));
while (*tmp != '"') {
if (*tmp == '~')
*tmp = ' ';
tmp++;
}
*tmp = '\0';
}
} }
tok = strtok(NULL, " ");
} }
/* now run the command, save the result if not successful */ /* now run the command, save the result if not successful */

View File

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

View File

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

View File

@ -34,10 +34,10 @@
* facility. * facility.
*/ */
#ifndef _BMC_INTF_H_ #ifndef _BMC_INTF_H
#define _BMC_INTF_H_ #define _BMC_INTF_H
#pragma ident "@(#)bmc_intf.h 1.2 04/08/25 SMI" #pragma ident "@(#)bmc_intf.h 1.2 05/03/07 SMI"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -46,13 +46,6 @@ extern "C" {
#define BMC_SUCCESS 0x0 #define BMC_SUCCESS 0x0
#define BMC_FAILURE 0x1 #define BMC_FAILURE 0x1
#define IPMI_SUCCESS BMC_SUCCESS
#define IPMI_FAILURE BMC_FAILURE
/* allau clean up */
#define IPMI_FALSE 0
#define IPMI_TRUE 1
#define BMC_NETFN_CHASSIS 0x0 #define BMC_NETFN_CHASSIS 0x0
#define BMC_NETFN_BRIDGE 0x2 #define BMC_NETFN_BRIDGE 0x2
#define BMC_NETFN_SE 0x4 #define BMC_NETFN_SE 0x4
@ -95,27 +88,38 @@ extern "C" {
#define IOCTL_IPMI_KCS_ACTION 0x01 #define IOCTL_IPMI_KCS_ACTION 0x01
#define IOCTL_IPMI_INTERFACE_METHOD 0x02
/* Interface methods returned from IOCTL_IPMI_INTERFACE_METHOD ioctl: */
#define BMC_IOCTL_METHOD 0 /* Not returned from ioctl, */
/* but can be used by */
/* applications that want to */
/* compare against an */
/* alternative method. */
#define BMC_PUTMSG_METHOD 1
/* /*
* bmc_req_t is the data structure to send * bmc_req_t is the data structure to send
* request packet from applications to the driver * request packet from applications to the driver
* module. * module.
*
* the request pkt is mainly for KCS-interface-BMC * the request pkt is mainly for KCS-interface-BMC
* messages. Since the system interface is session-less * messages. Since the system interface is session-less
* connections, the packet won't have any session * connections, the packet won't have any session
* information. * information.
*
* the data payload will be 2 bytes less than max * the data payload will be 2 bytes less than max
* BMC supported packet size. * BMC supported packet size.
* the address of the responder is always BMC and so * the address of the responder is always BMC and so
* rsSa field is not required. * rsSa field is not required.
*/ */
typedef struct bmc_req { typedef struct bmc_req {
unsigned char fn; /* netFn for command */ uint8_t fn; /* netFn for command */
unsigned char lun; /* logical unit on responder */ uint8_t lun; /* logical unit on responder */
unsigned char cmd; /* command */ uint8_t cmd; /* command */
unsigned char datalength; /* length of following data */ uint8_t datalength; /* length of following data */
unsigned char data[SEND_MAX_PAYLOAD_SIZE]; /* request data */ uint8_t data[SEND_MAX_PAYLOAD_SIZE]; /* request data */
} bmc_req_t; } bmc_req_t;
/* /*
@ -127,20 +131,21 @@ typedef struct bmc_req {
* messages. Since the system interface is session-less * messages. Since the system interface is session-less
* connections, the packet won't have any session * connections, the packet won't have any session
* information. * information.
*
* the data payload will be 2 bytes less than max * the data payload will be 2 bytes less than max
* BMC supported packet size. * BMC supported packet size.
*/ */
typedef struct bmc_rsp { typedef struct bmc_rsp {
unsigned char fn; /* netFn for command */ uint8_t fn; /* netFn for command */
unsigned char lun; /* logical unit on responder */ uint8_t lun; /* logical unit on responder */
unsigned char cmd; /* command */ uint8_t cmd; /* command */
unsigned char ccode; /* completion code */ uint8_t ccode; /* completion code */
unsigned char datalength; /* Length */ uint8_t datalength; /* Length */
unsigned char data[RECV_MAX_PAYLOAD_SIZE]; /* response */ uint8_t data[RECV_MAX_PAYLOAD_SIZE]; /* response */
} bmc_rsp_t; } bmc_rsp_t;
/* /*
* the data structure for synchronous operation. * the data structure for synchronous operation via ioctl (DEPRECATED)
*/ */
typedef struct bmc_reqrsp { typedef struct bmc_reqrsp {
bmc_req_t req; /* request half */ bmc_req_t req; /* request half */
@ -148,38 +153,59 @@ typedef struct bmc_reqrsp {
} bmc_reqrsp_t; } bmc_reqrsp_t;
#ifdef _KERNEL /*
* The new way of communicating with the bmc driver is to use putmsg() to
* send a message of a particular type. Replies from the driver also have this
* form, and will require the user to process the type field before examining
* the rest of the reply.
*
* The only change that must be observed when using the request and response
* structures defined above is as follows:
* when sending messages to the bmc driver, the data portion is now variable
* (the caller must allocate enough space to store the all structure members,
* plus enough space to cover the amount of data in the request), e.g.:
*
* bmc_msg_t *msg = malloc(offsetof(bmc_msg_t, msg) + sizeof(bmc_req_t) + 10);
*
* The amount allocated for the message is (# of bytes before the msg field) +
* the size of a bmc_req_t (which includes SEND_MAX_PAYLOAD_SIZE
* bytes in the data field), plus an additional 10 bytes for the data
* field (so the data field would occupy (SEND_MAX_PAYLOAD_SIZE + 10)
* bytes). The datalength member must reflect the amount of data in the
* request's data field (as was required when using the ioctl interface).
*/
typedef struct bmc_msg {
uint8_t m_type; /* Message type (see below) */
uint32_t m_id; /* Message ID */
uint8_t reserved[32];
uint8_t msg[1]; /* Variable length message data */
} bmc_msg_t;
/* /*
* data structure to send a message to BMC. * An error response passed back from the bmc driver will have its m_id
* Ref. IPMI Spec 9.2 * field set to BMC_UNKNOWN_MSG_ID if a message is sent to it that is not
* at least as large as a bmc_msg_t.
*/ */
typedef struct bmc_send { #define BMC_UNKNOWN_MSG_ID ~((uint32_t)0)
unsigned char fnlun; /* Network Function and LUN */
unsigned char cmd; /* command */
unsigned char data[SEND_MAX_PAYLOAD_SIZE];
} bmc_send_t;
/* /*
* data structure to receive a message from BMC. * Possible values for the m_type field in bmc_msg_t:
* Ref. IPMI Spec 9.3
*/ */
typedef struct bmc_recv { #define BMC_MSG_REQUEST 1 /* BMC request (as above, sent to the */
unsigned char fnlun; /* Network Function and LUN */ /* driver by the user), bmc_msg.msg */
unsigned char cmd; /* command */ /* begins with the bmc_req_t */
unsigned char ccode; /* completion code */ /* structure. */
unsigned char data[RECV_MAX_PAYLOAD_SIZE]; #define BMC_MSG_RESPONSE 2 /* BMC response (sent by the driver) */
} bmc_recv_t; /* bmc_msg.msg begins with the */
/* bmc_rsp_t structure. */
#define BMC_MSG_ERROR 3 /* Error while processing a user msg */
#endif /* _KERNEL */ /* msg[0] is the error code */
/* (interpret as an errno value) */
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#ifdef __cplusplus #endif /* _BMC_INTF_H */
}
#endif
#endif /* _BMC_INTF_H_ */

View File

@ -89,14 +89,29 @@ struct ipmi_intf * ipmi_intf_table[] = {
* *
* no meaningful return code * no meaningful return code
*/ */
void ipmi_intf_print(void) void ipmi_intf_print(struct ipmi_intf_support * intflist)
{ {
struct ipmi_intf ** intf; struct ipmi_intf ** intf;
struct ipmi_intf_support * sup;
int def = 1; int def = 1;
int found;
lprintf(LOG_NOTICE, "Interfaces:"); lprintf(LOG_NOTICE, "Interfaces:");
for (intf = ipmi_intf_table; intf && *intf; intf++) { for (intf = ipmi_intf_table; intf && *intf; intf++) {
if (intflist != NULL) {
found = 0;
for (sup=intflist; sup->name != NULL; sup++) {
if (strncmp(sup->name, (*intf)->name, strlen(sup->name)) == 0 &&
strncmp(sup->name, (*intf)->name, strlen((*intf)->name)) == 0 &&
sup->supported == 1)
found = 1;
}
if (found == 0)
continue;
}
lprintf(LOG_NOTICE, "\t%-12s %s %s", lprintf(LOG_NOTICE, "\t%-12s %s %s",
(*intf)->name, (*intf)->desc, (*intf)->name, (*intf)->desc,
def ? "[default]" : ""); def ? "[default]" : "");
@ -165,7 +180,7 @@ ipmi_intf_session_set_username(struct ipmi_intf * intf, char * username)
if (intf->session == NULL) if (intf->session == NULL)
return; return;
memset(intf->session->username, 0, 16); memset(intf->session->username, 0, 17);
if (username == NULL) if (username == NULL)
return; return;
@ -200,6 +215,39 @@ ipmi_intf_session_set_privlvl(struct ipmi_intf * intf, uint8_t level)
intf->session->privlvl = level; intf->session->privlvl = level;
} }
void
ipmi_intf_session_set_cipher_suite_id(struct ipmi_intf * intf, uint8_t cipher_suite_id)
{
if (intf->session == NULL)
return;
intf->session->cipher_suite_id = cipher_suite_id;
}
void
ipmi_intf_session_set_sol_escape_char(struct ipmi_intf * intf, char sol_escape_char)
{
if (intf->session == NULL)
return;
intf->session->sol_escape_char = sol_escape_char;
}
void
ipmi_intf_session_set_kgkey(struct ipmi_intf * intf, char * kgkey)
{
if (intf->session == NULL)
return;
memset(intf->session->v2_data.kg, 0, IPMI_KG_BUFFER_SIZE);
if (kgkey == NULL)
return;
memcpy(intf->session->v2_data.kg, kgkey,
__min(strlen(kgkey), IPMI_KG_BUFFER_SIZE));
}
void void
ipmi_intf_session_set_port(struct ipmi_intf * intf, int port) ipmi_intf_session_set_port(struct ipmi_intf * intf, int port)
{ {
@ -218,6 +266,24 @@ ipmi_intf_session_set_authtype(struct ipmi_intf * intf, uint8_t authtype)
intf->session->authtype_set = authtype; intf->session->authtype_set = authtype;
} }
void
ipmi_intf_session_set_timeout(struct ipmi_intf * intf, uint32_t timeout)
{
if (intf->session == NULL)
return;
intf->session->timeout = timeout;
}
void
ipmi_intf_session_set_retry(struct ipmi_intf * intf, int retry)
{
if (intf->session == NULL)
return;
intf->session->retry = retry;
}
void void
ipmi_cleanup(struct ipmi_intf * intf) ipmi_cleanup(struct ipmi_intf * intf)
{ {

View File

@ -75,6 +75,8 @@ static struct ipmi_rq_entry * ipmi_req_entries_tail;
extern int verbose; extern int verbose;
static uint8_t bridgePossible = 0;
static sigjmp_buf jmpbuf; static sigjmp_buf jmpbuf;
static int ipmi_lan_send_packet(struct ipmi_intf * intf, uint8_t * data, int data_len); static int ipmi_lan_send_packet(struct ipmi_intf * intf, uint8_t * data, int data_len);
@ -101,40 +103,6 @@ query_alarm(int signo)
siglongjmp(jmpbuf, 1); siglongjmp(jmpbuf, 1);
} }
static const struct valstr ipmi_channel_protocol_vals[] = {
{ 0x00, "reserved" },
{ 0x01, "IPMB-1.0" },
{ 0x02, "ICMB-1.0" },
{ 0x03, "reserved" },
{ 0x04, "IPMI-SMBus" },
{ 0x05, "KCS" },
{ 0x06, "SMIC" },
{ 0x07, "BT-10" },
{ 0x08, "BT-15" },
{ 0x09, "TMode" },
{ 0x1c, "OEM 1" },
{ 0x1d, "OEM 2" },
{ 0x1e, "OEM 3" },
{ 0x1f, "OEM 4" },
{ 0x00, NULL },
};
static const struct valstr ipmi_channel_medium_vals[] = {
{ 0x00, "reserved" },
{ 0x01, "IPMB (I2C)" },
{ 0x02, "ICMB v1.0" },
{ 0x03, "ICMB v0.9" },
{ 0x04, "802.3 LAN" },
{ 0x05, "Serial/Modem" },
{ 0x06, "Other LAN" },
{ 0x07, "PCI SMBus" },
{ 0x08, "SMBus v1.0/v1.1" },
{ 0x09, "SMBus v2.0" },
{ 0x0a, "USB 1.x" },
{ 0x0b, "USB 2.x" },
{ 0x0c, "System Interface" },
{ 0x00, NULL },
};
static struct ipmi_rq_entry * static struct ipmi_rq_entry *
ipmi_req_add_entry(struct ipmi_intf * intf, struct ipmi_rq * req) ipmi_req_add_entry(struct ipmi_intf * intf, struct ipmi_rq * req)
@ -168,7 +136,7 @@ ipmi_req_lookup_entry(uint8_t seq, uint8_t cmd)
{ {
struct ipmi_rq_entry * e = ipmi_req_entries; struct ipmi_rq_entry * e = ipmi_req_entries;
while (e && (e->rq_seq != seq || e->req.msg.cmd != cmd)) { while (e && (e->rq_seq != seq || e->req.msg.cmd != cmd)) {
if (e == e->next) if (e->next == NULL || e == e->next)
return NULL; return NULL;
e = e->next; e = e->next;
} }
@ -217,11 +185,17 @@ ipmi_req_clear_entries(void)
while (e) { while (e) {
lprintf(LOG_DEBUG+3, "cleared list entry seq=0x%02x cmd=0x%02x", lprintf(LOG_DEBUG+3, "cleared list entry seq=0x%02x cmd=0x%02x",
e->rq_seq, e->req.msg.cmd); e->rq_seq, e->req.msg.cmd);
if (e->next != NULL) {
p = e->next; p = e->next;
free(e); free(e);
e = p; e = p;
} else {
free(e);
break;
} }
} }
ipmi_req_entries = NULL;
}
static int static int
get_random(void *data, int len) get_random(void *data, int len)
@ -257,7 +231,7 @@ struct ipmi_rs * ipmi_lan_recv_packet(struct ipmi_intf * intf)
return NULL; return NULL;
} }
alarm(IPMI_LAN_TIMEOUT); alarm(intf->session->timeout);
rc = recv(intf->fd, &rsp.data, IPMI_BUF_SIZE, 0); rc = recv(intf->fd, &rsp.data, IPMI_BUF_SIZE, 0);
alarm(0); alarm(0);
@ -272,7 +246,7 @@ struct ipmi_rs * ipmi_lan_recv_packet(struct ipmi_intf * intf)
* response is read before the connection refused is returned) * response is read before the connection refused is returned)
*/ */
if (rc < 0) { if (rc < 0) {
alarm(IPMI_LAN_TIMEOUT); alarm(intf->session->timeout);
rc = recv(intf->fd, &rsp.data, IPMI_BUF_SIZE, 0); rc = recv(intf->fd, &rsp.data, IPMI_BUF_SIZE, 0);
alarm(0); alarm(0);
if (rc < 0) { if (rc < 0) {
@ -329,7 +303,7 @@ ipmi_handle_pong(struct ipmi_intf * intf, struct ipmi_rs * rsp)
" ASF Version %s\n" " ASF Version %s\n"
" RMCP Version %s\n" " RMCP Version %s\n"
" RMCP Sequence %d\n" " RMCP Sequence %d\n"
" IANA Enterprise %d\n", " IANA Enterprise %ld\n",
(pong->sup_entities & 0x80) ? "" : " NOT", (pong->sup_entities & 0x80) ? "" : " NOT",
(pong->sup_entities & 0x01) ? "1.0" : "unknown", (pong->sup_entities & 0x01) ? "1.0" : "unknown",
(pong->rmcp.ver == 6) ? "1.0" : "unknown", (pong->rmcp.ver == 6) ? "1.0" : "unknown",
@ -362,7 +336,7 @@ int
ipmi_lan_ping(struct ipmi_intf * intf) ipmi_lan_ping(struct ipmi_intf * intf)
{ {
struct asf_hdr asf_ping = { struct asf_hdr asf_ping = {
.iana = ASF_RMCP_IANA, .iana = htonl(ASF_RMCP_IANA),
.type = ASF_TYPE_PING, .type = ASF_TYPE_PING,
}; };
struct rmcp_hdr rmcp_ping = { struct rmcp_hdr rmcp_ping = {
@ -426,6 +400,14 @@ ipmi_lan_poll_recv(struct ipmi_intf * intf)
struct ipmi_rs * rsp; struct ipmi_rs * rsp;
struct ipmi_rq_entry * entry; struct ipmi_rq_entry * entry;
int x=0, rv; int x=0, rv;
uint8_t ourAddress = intf->my_addr;
if(ourAddress == 0)
{
ourAddress = IPMI_BMC_SLAVE_ADDR;
}
rsp = ipmi_lan_recv_packet(intf); rsp = ipmi_lan_recv_packet(intf);
@ -504,16 +486,29 @@ ipmi_lan_poll_recv(struct ipmi_intf * intf)
rsp->payload.ipmi_response.cmd); rsp->payload.ipmi_response.cmd);
if (entry) { if (entry) {
lprintf(LOG_DEBUG+2, "IPMI Request Match found"); lprintf(LOG_DEBUG+2, "IPMI Request Match found");
if (intf->target_addr != IPMI_BMC_SLAVE_ADDR) { if (
if (rsp->data_len) (intf->target_addr != ourAddress) &&
lprintf(LOG_DEBUG+1, "Bridged cmd %02x resp: %s", (bridgePossible)
rsp->payload.ipmi_response.cmd, )
buf2str(&rsp->data[x],rsp->data_len)); {
if(
(rsp->data_len) &&
(rsp->payload.ipmi_response.cmd != 0x34)
)
{
printbuf(
&rsp->data[x],
(rsp->data_len-x),
"bridge command response");
}
/* bridged command: lose extra header */ /* bridged command: lose extra header */
if (rsp->payload.ipmi_response.cmd == 0x34) { if (rsp->payload.ipmi_response.cmd == 0x34) {
if( rsp->data_len == 38 )
{
entry->req.msg.cmd = entry->req.msg.target_cmd; entry->req.msg.cmd = entry->req.msg.target_cmd;
rsp = ipmi_lan_recv_packet(intf); rsp = ipmi_lan_recv_packet(intf);
continue; continue;
}
} else { } else {
//x += sizeof(rsp->payload.ipmi_response); //x += sizeof(rsp->payload.ipmi_response);
if (rsp->data[x-1] != 0) if (rsp->data[x-1] != 0)
@ -587,6 +582,13 @@ ipmi_lan_build_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
struct ipmi_rq_entry * entry; struct ipmi_rq_entry * entry;
struct ipmi_session * s = intf->session; struct ipmi_session * s = intf->session;
static int curr_seq = 0; static int curr_seq = 0;
uint8_t ourAddress = intf->my_addr;
uint8_t bridgedRequest = 0;
if(ourAddress == 0)
{
ourAddress = IPMI_BMC_SLAVE_ADDR;
}
if (curr_seq >= 64) if (curr_seq >= 64)
curr_seq = 0; curr_seq = 0;
@ -627,15 +629,22 @@ ipmi_lan_build_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
} }
/* message length */ /* message length */
if (intf->target_addr == IPMI_BMC_SLAVE_ADDR) { if (
(intf->target_addr == ourAddress) ||
(!bridgePossible)
)
{
msg[len++] = req->msg.data_len + 7; msg[len++] = req->msg.data_len + 7;
cs = mp = len; cs = mp = len;
} }
else { else
{
/* bridged request: encapsulate w/in Send Message */ /* bridged request: encapsulate w/in Send Message */
bridgedRequest = 1;
msg[len++] = req->msg.data_len + 15; msg[len++] = req->msg.data_len + 15;
cs = mp = len; cs = mp = len;
msg[len++] = IPMI_BMC_SLAVE_ADDR; msg[len++] = IPMI_BMC_SLAVE_ADDR;
msg[len++] = IPMI_NETFN_APP << 2; msg[len++] = IPMI_NETFN_APP << 2;
tmp = len - cs; tmp = len - cs;
msg[len++] = ipmi_csum(msg+cs, tmp); msg[len++] = ipmi_csum(msg+cs, tmp);
@ -645,7 +654,7 @@ ipmi_lan_build_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
msg[len++] = 0x34; /* Send Message rqst */ msg[len++] = 0x34; /* Send Message rqst */
entry->req.msg.target_cmd = entry->req.msg.cmd; /* Save target command */ entry->req.msg.target_cmd = entry->req.msg.cmd; /* Save target command */
entry->req.msg.cmd = 0x34; /* (fixup request entry) */ entry->req.msg.cmd = 0x34; /* (fixup request entry) */
msg[len++] = 0x40; /* Track request, Channel=IPMB */ msg[len++] = (0x40|intf->target_channel); /* Track request*/
cs = len; cs = len;
} }
@ -655,8 +664,11 @@ ipmi_lan_build_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
tmp = len - cs; tmp = len - cs;
msg[len++] = ipmi_csum(msg+cs, tmp); msg[len++] = ipmi_csum(msg+cs, tmp);
cs = len; cs = len;
if (!bridgedRequest)
msg[len++] = IPMI_REMOTE_SWID; msg[len++] = IPMI_REMOTE_SWID;
else /* Bridged message */
msg[len++] = intf->my_addr;
entry->rq_seq = curr_seq++; entry->rq_seq = curr_seq++;
msg[len++] = entry->rq_seq << 2; msg[len++] = entry->rq_seq << 2;
msg[len++] = req->msg.cmd; msg[len++] = req->msg.cmd;
@ -686,11 +698,13 @@ ipmi_lan_build_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
msg[len++] = ipmi_csum(msg+cs, tmp); msg[len++] = ipmi_csum(msg+cs, tmp);
/* bridged request: 2nd checksum */ /* bridged request: 2nd checksum */
if (intf->target_addr != IPMI_BMC_SLAVE_ADDR) { if (bridgedRequest)
{
tmp = len - cs2; tmp = len - cs2;
msg[len++] = ipmi_csum(msg+cs2, tmp); msg[len++] = ipmi_csum(msg+cs2, tmp);
} }
if (s->active) { if (s->active) {
/* /*
* s->authcode is already copied to msg+ap but some * s->authcode is already copied to msg+ap but some
@ -725,7 +739,7 @@ struct ipmi_rs *
ipmi_lan_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req) ipmi_lan_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
{ {
struct ipmi_rq_entry * entry; struct ipmi_rq_entry * entry;
struct ipmi_rs * rsp; struct ipmi_rs * rsp = NULL;
int try = 0; int try = 0;
if (intf->opened == 0 && intf->open != NULL) { if (intf->opened == 0 && intf->open != NULL) {
@ -746,6 +760,10 @@ ipmi_lan_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
continue; continue;
} }
/* if we are set to noanswer we do not expect response */
if (intf->noanswer)
break;
if (ipmi_oem_active(intf, "intelwv2")) if (ipmi_oem_active(intf, "intelwv2"))
ipmi_lan_thump(intf); ipmi_lan_thump(intf);
@ -756,7 +774,7 @@ ipmi_lan_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
break; break;
usleep(5000); usleep(5000);
if (++try >= IPMI_LAN_RETRY) { if (++try >= intf->session->retry) {
lprintf(LOG_DEBUG, " No response from remote controller"); lprintf(LOG_DEBUG, " No response from remote controller");
break; break;
} }
@ -1127,7 +1145,7 @@ ipmi_activate_session_cmd(struct ipmi_intf * intf)
printbuf(rsp->data, rsp->data_len, "activate_session"); printbuf(rsp->data, rsp->data_len, "activate_session");
if (rsp->ccode) { if (rsp->ccode) {
lprintf(LOG_ERR, "Activate Session error:"); fprintf(stderr, "Activate Session error:");
switch (rsp->ccode) { switch (rsp->ccode) {
case 0x81: case 0x81:
lprintf(LOG_ERR, "\tNo session slot available"); lprintf(LOG_ERR, "\tNo session slot available");
@ -1173,6 +1191,8 @@ ipmi_activate_session_cmd(struct ipmi_intf * intf)
return -1; return -1;
} }
bridgePossible = 1;
lprintf(LOG_DEBUG, "\nSession Activated"); lprintf(LOG_DEBUG, "\nSession Activated");
lprintf(LOG_DEBUG, " Auth Type : %s", lprintf(LOG_DEBUG, " Auth Type : %s",
val2str(rsp->data[0], ipmi_authtype_session_vals)); val2str(rsp->data[0], ipmi_authtype_session_vals));
@ -1194,6 +1214,7 @@ ipmi_set_session_privlvl_cmd(struct ipmi_intf * intf)
struct ipmi_rs * rsp; struct ipmi_rs * rsp;
struct ipmi_rq req; struct ipmi_rq req;
uint8_t privlvl = intf->session->privlvl; uint8_t privlvl = intf->session->privlvl;
uint8_t backupBridgePossible = bridgePossible;
if (privlvl <= IPMI_SESSION_PRIV_USER) if (privlvl <= IPMI_SESSION_PRIV_USER)
return 0; /* no need to set higher */ return 0; /* no need to set higher */
@ -1204,7 +1225,12 @@ ipmi_set_session_privlvl_cmd(struct ipmi_intf * intf)
req.msg.data = &privlvl; req.msg.data = &privlvl;
req.msg.data_len = 1; req.msg.data_len = 1;
bridgePossible = 0;
rsp = intf->sendrecv(intf, &req); rsp = intf->sendrecv(intf, &req);
bridgePossible = backupBridgePossible;
if (rsp == NULL) { if (rsp == NULL) {
lprintf(LOG_ERR, "Set Session Privilege Level to %s failed", lprintf(LOG_ERR, "Set Session Privilege Level to %s failed",
val2str(privlvl, ipmi_privlvl_vals)); val2str(privlvl, ipmi_privlvl_vals));
@ -1215,7 +1241,8 @@ ipmi_set_session_privlvl_cmd(struct ipmi_intf * intf)
if (rsp->ccode > 0) { if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Set Session Privilege Level to %s failed: %s", lprintf(LOG_ERR, "Set Session Privilege Level to %s failed: %s",
val2str(privlvl, ipmi_privlvl_vals)); val2str(privlvl, ipmi_privlvl_vals),
val2str(rsp->ccode, completion_code_vals));
return -1; return -1;
} }
@ -1237,6 +1264,7 @@ ipmi_close_session_cmd(struct ipmi_intf * intf)
return -1; return -1;
intf->target_addr = IPMI_BMC_SLAVE_ADDR; intf->target_addr = IPMI_BMC_SLAVE_ADDR;
bridgePossible = 0; /* Not a bridge message */
memcpy(&msg_data, &session_id, 4); memcpy(&msg_data, &session_id, 4);
@ -1295,7 +1323,7 @@ ipmi_lan_activate_session(struct ipmi_intf * intf)
/* don't fail on ping because its not always supported. /* don't fail on ping because its not always supported.
* Supermicro's IPMI LAN 1.5 cards don't tolerate pings. * Supermicro's IPMI LAN 1.5 cards don't tolerate pings.
*/ */
if (ipmi_oem_active(intf, "supermicro")) if (!ipmi_oem_active(intf, "supermicro"))
ipmi_lan_ping(intf); ipmi_lan_ping(intf);
/* Some particular Intel boards need special help /* Some particular Intel boards need special help
@ -1319,12 +1347,12 @@ ipmi_lan_activate_session(struct ipmi_intf * intf)
if (rc < 0) if (rc < 0)
goto fail; goto fail;
intf->abort = 0;
rc = ipmi_set_session_privlvl_cmd(intf); rc = ipmi_set_session_privlvl_cmd(intf);
if (rc < 0) if (rc < 0)
goto fail; goto fail;
intf->abort = 0;
return 0; return 0;
fail: fail:
@ -1365,6 +1393,10 @@ int ipmi_lan_open(struct ipmi_intf * intf)
s->port = IPMI_LAN_PORT; s->port = IPMI_LAN_PORT;
if (s->privlvl == 0) if (s->privlvl == 0)
s->privlvl = IPMI_SESSION_PRIV_ADMIN; s->privlvl = IPMI_SESSION_PRIV_ADMIN;
if (s->timeout == 0)
s->timeout = IPMI_LAN_TIMEOUT;
if (s->retry == 0)
s->retry = IPMI_LAN_RETRY;
if (s->hostname == NULL || strlen(s->hostname) == 0) { if (s->hostname == NULL || strlen(s->hostname) == 0) {
lprintf(LOG_ERR, "No hostname specified!"); lprintf(LOG_ERR, "No hostname specified!");
@ -1378,7 +1410,11 @@ int ipmi_lan_open(struct ipmi_intf * intf)
s->addr.sin_family = AF_INET; s->addr.sin_family = AF_INET;
s->addr.sin_port = htons(s->port); s->addr.sin_port = htons(s->port);
#ifdef __CYGWIN__
rc = inet_aton(s->hostname, &s->addr.sin_addr);
#else
rc = inet_pton(AF_INET, s->hostname, &s->addr.sin_addr); rc = inet_pton(AF_INET, s->hostname, &s->addr.sin_addr);
#endif
if (rc <= 0) { if (rc <= 0) {
struct hostent *host = gethostbyname(s->hostname); struct hostent *host = gethostbyname(s->hostname);
if (host == NULL) { if (host == NULL) {

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -71,12 +71,13 @@
* 1 on failure (the authcode does not match) * 1 on failure (the authcode does not match)
*/ */
int lanplus_rakp2_hmac_matches(const struct ipmi_session * session, int lanplus_rakp2_hmac_matches(const struct ipmi_session * session,
const uint8_t * bmc_mac) const uint8_t * bmc_mac,
struct ipmi_intf * intf)
{ {
char * buffer; char * buffer;
int bufferLength, i; int bufferLength, i;
uint8_t mac[20]; uint8_t mac[20];
int macLength; uint32_t macLength;
uint32_t SIDm_lsbf, SIDc_lsbf; uint32_t SIDm_lsbf, SIDc_lsbf;
@ -84,7 +85,7 @@ int lanplus_rakp2_hmac_matches(const struct ipmi_session * session,
if (session->v2_data.auth_alg == IPMI_AUTH_RAKP_NONE) if (session->v2_data.auth_alg == IPMI_AUTH_RAKP_NONE)
return 1; return 1;
/* We don't yet support other alogrithms */ /* We don't yet support other algorithms */
assert(session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_SHA1); assert(session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_SHA1);
@ -167,14 +168,12 @@ int lanplus_rakp2_hmac_matches(const struct ipmi_session * session,
printbuf((char*)(session->authcode), IPMI_AUTHCODE_BUFFER_SIZE, ">> rakp2 mac key"); printbuf((char*)(session->authcode), IPMI_AUTHCODE_BUFFER_SIZE, ">> rakp2 mac key");
} }
/* /*
* The buffer is complete. Let's hash. * The buffer is complete. Let's hash.
*/ */
lanplus_HMAC(session->v2_data.auth_alg, lanplus_HMAC(session->v2_data.auth_alg,
session->authcode, session->authcode,
(session->authcode[IPMI_AUTHCODE_BUFFER_SIZE] == 0? IPMI_AUTHCODE_BUFFER_SIZE,
strlen(session->authcode): IPMI_AUTHCODE_BUFFER_SIZE),
buffer, buffer,
bufferLength, bufferLength,
mac, mac,
@ -211,25 +210,36 @@ int lanplus_rakp2_hmac_matches(const struct ipmi_session * session,
* *
* If the authentication algorithm is IPMI_AUTH_RAKP_NONE, we return success. * If the authentication algorithm is IPMI_AUTH_RAKP_NONE, we return success.
* *
* return 0 on success (the authcode matches) * return 1 on success (the authcode matches)
* 1 on failure (the authcode does not match) * 0 on failure (the authcode does not match)
*
*/ */
int lanplus_rakp4_hmac_matches(const struct ipmi_session * session, int lanplus_rakp4_hmac_matches(const struct ipmi_session * session,
const uint8_t * bmc_mac) const uint8_t * bmc_mac,
struct ipmi_intf * intf)
{ {
char * buffer; char * buffer;
int bufferLength, i; int bufferLength, i;
uint8_t mac[20]; uint8_t mac[20];
int macLength; uint32_t macLength;
uint32_t SIDc_lsbf; uint32_t SIDc_lsbf;
if (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) if (session->v2_data.auth_alg == IPMI_AUTH_RAKP_NONE)
return 1; return 1;
/* We don't yet support other alogrithms */ /* We don't yet support other algorithms */
assert(session->v2_data.auth_alg == IPMI_INTEGRITY_HMAC_SHA1_96); assert(session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_SHA1);
}
bufferLength = bufferLength =
16 + /* Rm */ 16 + /* Rm */
@ -285,9 +295,11 @@ int lanplus_rakp4_hmac_matches(const struct ipmi_session * session,
/* /*
* The buffer is complete. Let's hash. * The buffer is complete. Let's hash.
*/ */
lanplus_HMAC(session->v2_data.auth_alg, lanplus_HMAC((ipmi_oem_active(intf, "intelplus"))
? session->v2_data.integrity_alg
: session->v2_data.auth_alg ,
session->v2_data.sik, session->v2_data.sik,
20, IPMI_SIK_BUFFER_SIZE,
buffer, buffer,
bufferLength, bufferLength,
mac, mac,
@ -295,6 +307,7 @@ int lanplus_rakp4_hmac_matches(const struct ipmi_session * session,
if (verbose > 2) if (verbose > 2)
{ {
printbuf(bmc_mac, macLength, ">> rakp4 mac as computed by the BMC");
printbuf(mac, macLength, ">> rakp4 mac as computed by the remote console"); printbuf(mac, macLength, ">> rakp4 mac as computed by the remote console");
} }
@ -332,7 +345,8 @@ int lanplus_rakp4_hmac_matches(const struct ipmi_session * session,
*/ */
int lanplus_generate_rakp3_authcode(char * output_buffer, int lanplus_generate_rakp3_authcode(char * output_buffer,
const struct ipmi_session * session, const struct ipmi_session * session,
uint32_t * mac_length) uint32_t * mac_length,
struct ipmi_intf * intf)
{ {
int ret = 0; int ret = 0;
int input_buffer_length, i; int input_buffer_length, i;
@ -346,7 +360,7 @@ int lanplus_generate_rakp3_authcode(char * output_buffer,
return 0; return 0;
} }
/* We don't yet support other alogrithms */ /* We don't yet support other algorithms */
assert(session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_SHA1); assert(session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_SHA1);
input_buffer_length = input_buffer_length =
@ -384,6 +398,9 @@ int lanplus_generate_rakp3_authcode(char * output_buffer,
memcpy(input_buffer + 16, &SIDm_lsbf, 4); memcpy(input_buffer + 16, &SIDm_lsbf, 4);
/* ROLEm */ /* ROLEm */
if (ipmi_oem_active(intf, "intelplus"))
input_buffer[20] = session->privlvl;
else
input_buffer[20] = session->v2_data.requested_role; input_buffer[20] = session->v2_data.requested_role;
/* ULENGTHm */ /* ULENGTHm */
@ -399,11 +416,9 @@ int lanplus_generate_rakp3_authcode(char * output_buffer,
printbuf((char*)(session->authcode), IPMI_AUTHCODE_BUFFER_SIZE, ">> rakp3 mac key"); printbuf((char*)(session->authcode), IPMI_AUTHCODE_BUFFER_SIZE, ">> rakp3 mac key");
} }
lanplus_HMAC(session->v2_data.auth_alg, lanplus_HMAC(session->v2_data.auth_alg,
session->authcode, session->authcode,
(session->authcode[IPMI_AUTHCODE_BUFFER_SIZE - 1] == 0? IPMI_AUTHCODE_BUFFER_SIZE,
strlen(session->authcode): IPMI_AUTHCODE_BUFFER_SIZE),
input_buffer, input_buffer,
input_buffer_length, input_buffer_length,
output_buffer, output_buffer,
@ -451,8 +466,7 @@ int lanplus_generate_sik(struct ipmi_session * session)
char * input_buffer; char * input_buffer;
int input_buffer_length, i; int input_buffer_length, i;
char * input_key; char * input_key;
int input_key_length; uint32_t mac_length;
int mac_length;
memset(session->v2_data.sik, 0, IPMI_SIK_BUFFER_SIZE); memset(session->v2_data.sik, 0, IPMI_SIK_BUFFER_SIZE);
@ -460,7 +474,7 @@ int lanplus_generate_sik(struct ipmi_session * session)
if (session->v2_data.auth_alg == IPMI_AUTH_RAKP_NONE) if (session->v2_data.auth_alg == IPMI_AUTH_RAKP_NONE)
return 0; return 0;
/* We don't yet support other alogrithms */ /* We don't yet support other algorithms */
assert(session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_SHA1); assert(session->v2_data.auth_alg == IPMI_AUTH_RAKP_HMAC_SHA1);
input_buffer_length = input_buffer_length =
@ -514,28 +528,25 @@ int lanplus_generate_sik(struct ipmi_session * session)
{ {
/* We will be hashing with Kg */ /* We will be hashing with Kg */
/* /*
* TODO: Section 13.31 of the IPMI v2 spec describes the SIK creation * Section 13.31 of the IPMI v2 spec describes the SIK creation
* using Kg. It specifies that Kg should not be truncated, but I * using Kg. It specifies that Kg should not be truncated.
* do not know what is meant by that. * Kg is set in ipmi_intf.
*/ */
lprintf(LOG_ERR, "lanplus_generate_sik: We dont yet support hashing with Kg");
assert(0);
input_key = session->v2_data.kg; input_key = session->v2_data.kg;
input_key_length = strlen(session->v2_data.kg);
} }
else else
{ {
/* We will be hashing with Kuid */ /* We will be hashing with Kuid */
input_key = session->authcode; input_key = session->authcode;
input_key_length = (session->authcode[IPMI_AUTHCODE_BUFFER_SIZE - 1] == 0?
strlen(session->authcode): IPMI_AUTHCODE_BUFFER_SIZE);
} }
if (verbose >= 2)
printbuf(input_buffer, input_buffer_length, "session integrity key input");
lanplus_HMAC(session->v2_data.auth_alg, lanplus_HMAC(session->v2_data.auth_alg,
input_key, input_key,
input_key_length, IPMI_AUTHCODE_BUFFER_SIZE,
input_buffer, input_buffer,
input_buffer_length, input_buffer_length,
session->v2_data.sik, session->v2_data.sik,
@ -583,7 +594,7 @@ int lanplus_generate_k1(struct ipmi_session * session)
{ {
lanplus_HMAC(session->v2_data.auth_alg, lanplus_HMAC(session->v2_data.auth_alg,
session->v2_data.sik, session->v2_data.sik,
20, /* SIK length */ IPMI_SIK_BUFFER_SIZE, /* SIK length */
CONST_1, CONST_1,
20, 20,
session->v2_data.k1, session->v2_data.k1,
@ -626,7 +637,7 @@ int lanplus_generate_k2(struct ipmi_session * session)
{ {
lanplus_HMAC(session->v2_data.auth_alg, lanplus_HMAC(session->v2_data.auth_alg,
session->v2_data.sik, session->v2_data.sik,
20, /* SIK length */ IPMI_SIK_BUFFER_SIZE, /* SIK length */
CONST_2, CONST_2,
20, 20,
session->v2_data.k2, session->v2_data.k2,
@ -675,7 +686,6 @@ int lanplus_encrypt_payload(uint8_t crypt_alg,
if (crypt_alg == IPMI_CRYPT_NONE) if (crypt_alg == IPMI_CRYPT_NONE)
{ {
lprintf(LOG_WARNING, "NOT ENCRYPTING");
/* Just copy the input to the output */ /* Just copy the input to the output */
*bytes_written = input_length; *bytes_written = input_length;
return 0; return 0;
@ -683,7 +693,7 @@ int lanplus_encrypt_payload(uint8_t crypt_alg,
/* Currently, we only support AES */ /* Currently, we only support AES */
assert(crypt_alg == IPMI_CRYPT_AES_CBC_128); assert(crypt_alg == IPMI_CRYPT_AES_CBC_128);
assert(input_length <= 255); assert(input_length <= IPMI_MAX_PAYLOAD_SIZE);
/* /*
@ -786,7 +796,7 @@ int lanplus_has_valid_auth_code(struct ipmi_rs * rs,
lanplus_HMAC(session->v2_data.integrity_alg, lanplus_HMAC(session->v2_data.integrity_alg,
session->v2_data.k1, session->v2_data.k1,
20, IPMI_AUTHCODE_BUFFER_SIZE,
rs->data + IMPI_LANPLUS_OFFSET_AUTHTYPE, rs->data + IMPI_LANPLUS_OFFSET_AUTHTYPE,
rs->data_len - IMPI_LANPLUS_OFFSET_AUTHTYPE - IPMI_SHA1_AUTHCODE_SIZE, rs->data_len - IMPI_LANPLUS_OFFSET_AUTHTYPE - IPMI_SHA1_AUTHCODE_SIZE,
generated_authcode, generated_authcode,

View File

@ -41,15 +41,20 @@
/* /*
* See the implementation file for documentation * See the implementation file for documentation
* ipmi_intf can be used for oem specific implementations
* e.g. if (ipmi_oem_active(intf, "OEM_XYZ"))
*/ */
int lanplus_rakp2_hmac_matches(const struct ipmi_session * session, int lanplus_rakp2_hmac_matches(const struct ipmi_session * session,
const uint8_t * hmac); const uint8_t * hmac,
struct ipmi_intf * intf);
int lanplus_rakp4_hmac_matches(const struct ipmi_session * session, int lanplus_rakp4_hmac_matches(const struct ipmi_session * session,
const uint8_t * hmac); const uint8_t * hmac,
struct ipmi_intf * intf);
int lanplus_generate_rakp3_authcode(char * buffer, int lanplus_generate_rakp3_authcode(char * buffer,
const struct ipmi_session * session, const struct ipmi_session * session,
uint32_t * auth_length); uint32_t * auth_length,
struct ipmi_intf * intf);
int lanplus_generate_sik(struct ipmi_session * session); int lanplus_generate_sik(struct ipmi_session * session);
int lanplus_generate_k1(struct ipmi_session * session); int lanplus_generate_k1(struct ipmi_session * session);
int lanplus_generate_k2(struct ipmi_session * session); int lanplus_generate_k2(struct ipmi_session * session);

View File

@ -34,6 +34,7 @@
* facility. * facility.
*/ */
#include "ipmitool/ipmi_constants.h"
#include "lanplus.h" #include "lanplus.h"
#include "lanplus_crypt_impl.h" #include "lanplus_crypt_impl.h"
#include <openssl/hmac.h> #include <openssl/hmac.h>
@ -79,7 +80,7 @@ int lanplus_seed_prng(uint32_t bytes)
int int
lanplus_rand(uint8_t * buffer, uint32_t num_bytes) lanplus_rand(uint8_t * buffer, uint32_t num_bytes)
{ {
#define IPMI_LANPLUS_FAKE_RAND 1 #undef IPMI_LANPLUS_FAKE_RAND
#ifdef IPMI_LANPLUS_FAKE_RAND #ifdef IPMI_LANPLUS_FAKE_RAND
/* /*
@ -133,7 +134,7 @@ lanplus_HMAC(uint8_t mac,
} }
return HMAC(evp_md, key, key_len, d, n, md, md_len); return HMAC(evp_md, key, key_len, d, n, md, (unsigned int *)md_len);
} }
@ -162,6 +163,7 @@ lanplus_encrypt_aes_cbc_128(const uint8_t * iv,
EVP_CIPHER_CTX ctx; EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx); EVP_CIPHER_CTX_init(&ctx);
EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key, iv); EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key, iv);
EVP_CIPHER_CTX_set_padding(&ctx, 0);
*bytes_written = 0; *bytes_written = 0;
@ -185,7 +187,7 @@ lanplus_encrypt_aes_cbc_128(const uint8_t * iv,
assert((input_length % IPMI_CRYPT_AES_CBC_128_BLOCK_SIZE) == 0); assert((input_length % IPMI_CRYPT_AES_CBC_128_BLOCK_SIZE) == 0);
if(!EVP_EncryptUpdate(&ctx, output, bytes_written, input, input_length)) if(!EVP_EncryptUpdate(&ctx, output, (unsigned int *)bytes_written, input, input_length))
{ {
/* Error */ /* Error */
*bytes_written = 0; *bytes_written = 0;
@ -195,7 +197,7 @@ lanplus_encrypt_aes_cbc_128(const uint8_t * iv,
{ {
uint32_t tmplen; uint32_t tmplen;
if(!EVP_EncryptFinal_ex(&ctx, output + *bytes_written, &tmplen)) if(!EVP_EncryptFinal_ex(&ctx, output + *bytes_written, (unsigned int *)&tmplen))
{ {
*bytes_written = 0; *bytes_written = 0;
return; /* Error */ return; /* Error */
@ -236,6 +238,8 @@ lanplus_decrypt_aes_cbc_128(const uint8_t * iv,
EVP_CIPHER_CTX ctx; EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx); EVP_CIPHER_CTX_init(&ctx);
EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key, iv); EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key, iv);
EVP_CIPHER_CTX_set_padding(&ctx, 0);
if (verbose > 2) if (verbose > 2)
@ -259,7 +263,7 @@ lanplus_decrypt_aes_cbc_128(const uint8_t * iv,
assert((input_length % IPMI_CRYPT_AES_CBC_128_BLOCK_SIZE) == 0); assert((input_length % IPMI_CRYPT_AES_CBC_128_BLOCK_SIZE) == 0);
if (!EVP_DecryptUpdate(&ctx, output, bytes_written, input, input_length)) if (!EVP_DecryptUpdate(&ctx, output, (unsigned int *)bytes_written, input, input_length))
{ {
/* Error */ /* Error */
fprintf(stderr, "ERROR: decrypt update failed"); fprintf(stderr, "ERROR: decrypt update failed");
@ -270,7 +274,7 @@ lanplus_decrypt_aes_cbc_128(const uint8_t * iv,
{ {
uint32_t tmplen; uint32_t tmplen;
if (!EVP_DecryptFinal_ex(&ctx, output + *bytes_written, &tmplen)) if (!EVP_DecryptFinal_ex(&ctx, output + *bytes_written, (unsigned int *)&tmplen))
{ {
char buffer[1000]; char buffer[1000];
ERR_error_string(ERR_get_error(), buffer); ERR_error_string(ERR_get_error(), buffer);

View File

@ -47,6 +47,9 @@ extern const struct valstr ipmi_encryption_algorithms[];
void lanplus_dump_open_session_response(const struct ipmi_rs * rsp) void lanplus_dump_open_session_response(const struct ipmi_rs * rsp)
{ {
if (verbose < 2)
return;
printf("%sOPEN SESSION RESPONSE\n", DUMP_PREFIX_INCOMING); printf("%sOPEN SESSION RESPONSE\n", DUMP_PREFIX_INCOMING);
printf("%s Message tag : 0x%02x\n", printf("%s Message tag : 0x%02x\n",
@ -63,6 +66,12 @@ void lanplus_dump_open_session_response(const struct ipmi_rs * rsp)
printf("%s Console Session ID : 0x%08lx\n", printf("%s Console Session ID : 0x%08lx\n",
DUMP_PREFIX_INCOMING, DUMP_PREFIX_INCOMING,
(long)rsp->payload.open_session_response.console_id); (long)rsp->payload.open_session_response.console_id);
/* only tag, status, privlvl, and console id are returned if error */
if (rsp->payload.open_session_response.rakp_return_code !=
IPMI_RAKP_STATUS_NO_ERRORS)
return;
printf("%s BMC Session ID : 0x%08lx\n", printf("%s BMC Session ID : 0x%08lx\n",
DUMP_PREFIX_INCOMING, DUMP_PREFIX_INCOMING,
(long)rsp->payload.open_session_response.bmc_id); (long)rsp->payload.open_session_response.bmc_id);
@ -87,6 +96,9 @@ void lanplus_dump_rakp2_message(const struct ipmi_rs * rsp, uint8_t auth_alg)
{ {
int i; int i;
if (verbose < 2)
return;
printf("%sRAKP 2 MESSAGE\n", DUMP_PREFIX_INCOMING); printf("%sRAKP 2 MESSAGE\n", DUMP_PREFIX_INCOMING);
printf("%s Message tag : 0x%02x\n", printf("%s Message tag : 0x%02x\n",
@ -141,30 +153,23 @@ void lanplus_dump_rakp4_message(const struct ipmi_rs * rsp, uint8_t auth_alg)
{ {
int i; int i;
if (verbose < 2)
return;
printf("%sRAKP 4 MESSAGE\n", DUMP_PREFIX_INCOMING); printf("%sRAKP 4 MESSAGE\n", DUMP_PREFIX_INCOMING);
printf("%s Message tag : 0x%02x\n", printf("%s Message tag : 0x%02x\n",
DUMP_PREFIX_INCOMING, DUMP_PREFIX_INCOMING,
rsp->payload.rakp2_message.message_tag); rsp->payload.rakp4_message.message_tag);
printf("%s RMCP+ status : %s\n", printf("%s RMCP+ status : %s\n",
DUMP_PREFIX_INCOMING, DUMP_PREFIX_INCOMING,
val2str(rsp->payload.rakp2_message.rakp_return_code, val2str(rsp->payload.rakp4_message.rakp_return_code,
ipmi_rakp_return_codes)); ipmi_rakp_return_codes));
printf("%s Console Session ID : 0x%08lx\n", printf("%s Console Session ID : 0x%08lx\n",
DUMP_PREFIX_INCOMING, DUMP_PREFIX_INCOMING,
(long)rsp->payload.rakp2_message.console_id); (long)rsp->payload.rakp4_message.console_id);
printf("%s BMC random number : 0x", DUMP_PREFIX_INCOMING);
for (i = 0; i < 16; ++i)
printf("%02x", rsp->payload.rakp2_message.bmc_rand[i]);
printf("\n");
printf("%s BMC GUID : 0x", DUMP_PREFIX_INCOMING);
for (i = 0; i < 16; ++i)
printf("%02x", rsp->payload.rakp2_message.bmc_guid[i]);
printf("\n");
switch(auth_alg) switch(auth_alg)
{ {

View File

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

View File

@ -52,6 +52,7 @@
#include <config.h> #include <config.h>
#ifdef HAVE_OPENIPMI_H #ifdef HAVE_OPENIPMI_H
# include <linux/compiler.h>
# include <linux/ipmi.h> # include <linux/ipmi.h>
#else #else
# include "open.h" # include "open.h"
@ -61,20 +62,31 @@ extern int verbose;
#define IPMI_OPENIPMI_DEV "/dev/ipmi0" #define IPMI_OPENIPMI_DEV "/dev/ipmi0"
#define IPMI_OPENIPMI_DEVFS "/dev/ipmi/0" #define IPMI_OPENIPMI_DEVFS "/dev/ipmi/0"
#define IPMI_OPENIPMI_DEVFS2 "/dev/ipmidev/0"
static int static int
ipmi_openipmi_open(struct ipmi_intf * intf) ipmi_openipmi_open(struct ipmi_intf * intf)
{ {
int i = 0; int i = 0;
#ifdef INCLUDE_PICMG_GET_DEVICE_LOCATOR
struct ipmi_rq req;
struct ipmi_rs *rsp;
char msg_data;
#endif
intf->fd = open(IPMI_OPENIPMI_DEV, O_RDWR); intf->fd = open(IPMI_OPENIPMI_DEV, O_RDWR);
if (intf->fd < 0) { if (intf->fd < 0) {
intf->fd = open(IPMI_OPENIPMI_DEVFS, O_RDWR); intf->fd = open(IPMI_OPENIPMI_DEVFS, O_RDWR);
lperror(LOG_ERR, "Could not open device at %s or %s", if (intf->fd < 0) {
IPMI_OPENIPMI_DEV, IPMI_OPENIPMI_DEVFS); intf->fd = open(IPMI_OPENIPMI_DEVFS2, O_RDWR);
}
if (intf->fd < 0) {
lperror(LOG_ERR, "Could not open device at %s or %s or %s",
IPMI_OPENIPMI_DEV, IPMI_OPENIPMI_DEVFS , IPMI_OPENIPMI_DEVFS2);
return -1; return -1;
} }
}
if (ioctl(intf->fd, IPMICTL_SET_GETS_EVENTS_CMD, &i) < 0) { if (ioctl(intf->fd, IPMICTL_SET_GETS_EVENTS_CMD, &i) < 0) {
lperror(LOG_ERR, "Could not enable event receiver"); lperror(LOG_ERR, "Could not enable event receiver");
@ -90,9 +102,36 @@ ipmi_openipmi_open(struct ipmi_intf * intf)
lprintf(LOG_DEBUG, "Set IPMB address to 0x%x", lprintf(LOG_DEBUG, "Set IPMB address to 0x%x",
intf->my_addr); intf->my_addr);
} }
intf->opened = 1; intf->opened = 1;
#ifdef INCLUDE_PICMG_GET_DEVICE_LOCATOR
/* PICMG hack to set right IPMB address,
we might want to do GetPICMGProperties first.
In any case, on a server board or a non-picmg IpmC blade , this code
will not have any adverse side effect
*/
if ( (intf->my_addr == IPMI_BMC_SLAVE_ADDR) ) {
lprintf(LOG_DEBUG, "Running PICMG GetDeviceLocator" );
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_PICMG;
req.msg.cmd = 0x01;
msg_data = 0x00;
req.msg.data = &msg_data;
req.msg.data_len = 1;
msg_data = 0;
rsp = intf->sendrecv(intf, &req);
if (rsp) {
if ( !rsp->ccode ) {
intf->my_addr = rsp->data[2];
intf->target_addr = intf->my_addr;
lprintf(LOG_DEBUG, "Discovered IPMB address = 0x%x", intf->my_addr);
}
}
}
#endif
return intf->fd; return intf->fd;
} }
@ -118,6 +157,7 @@ ipmi_openipmi_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
}; };
struct ipmi_ipmb_addr ipmb_addr = { struct ipmi_ipmb_addr ipmb_addr = {
addr_type: IPMI_IPMB_ADDR_TYPE, addr_type: IPMI_IPMB_ADDR_TYPE,
channel: intf->target_channel & 0x0f,
}; };
struct ipmi_req _req; struct ipmi_req _req;
static struct ipmi_rs rsp; static struct ipmi_rs rsp;
@ -152,6 +192,7 @@ ipmi_openipmi_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
/* otherwise use system interface */ /* otherwise use system interface */
lprintf(LOG_DEBUG+2, "Sending request to " lprintf(LOG_DEBUG+2, "Sending request to "
"System Interface"); "System Interface");
bmc_addr.lun = req->msg.lun;
_req.addr = (char *) &bmc_addr; _req.addr = (char *) &bmc_addr;
_req.addr_len = sizeof(bmc_addr); _req.addr_len = sizeof(bmc_addr);
} }
@ -171,6 +212,9 @@ ipmi_openipmi_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
* wait for and retrieve response * wait for and retrieve response
*/ */
if (intf->noanswer)
return NULL;
FD_ZERO(&rset); FD_ZERO(&rset);
FD_SET(intf->fd, &rset); FD_SET(intf->fd, &rset);