mirror of
https://github.com/ipmitool/ipmitool.git
synced 2025-07-01 02:03:50 +00:00
Compare commits
49 Commits
feature/ad
...
feature/re
Author | SHA1 | Date | |
---|---|---|---|
a6ff7b6cfb | |||
f80effb1fc | |||
7ccea283dd | |||
d45572d71e | |||
9452be8718 | |||
41d7026946 | |||
840fb1cbb4 | |||
e824c23316 | |||
7a66d8725d | |||
63dd71c39c | |||
e60eac12cc | |||
dec04e79fd | |||
d9adbf12f1 | |||
5647cd16d2 | |||
42a023ff07 | |||
58c9263a28 | |||
0663814eec | |||
aa72d9c426 | |||
0854344db5 | |||
4b89f1b42d | |||
0e3e436eb6 | |||
eed9d5950e | |||
4dc962b614 | |||
6940a6717a | |||
51a2ab8180 | |||
af062a9a5e | |||
1724b031b3 | |||
9006f2b26d | |||
b7db637984 | |||
82d6629a66 | |||
c396a310ba | |||
002e1d95f5 | |||
2ee7aca4e4 | |||
efd28d1bc1 | |||
d95775288d | |||
ef78ef3792 | |||
2676ae43fd | |||
54abbaf0e8 | |||
bd0475ce4a | |||
b397a07e9e | |||
8071cf7389 | |||
ca7767793e | |||
a45704e5ea | |||
94f7646a8e | |||
62a04390e1 | |||
de1d5c9924 | |||
73d6af5782 | |||
c9510635d7 | |||
e11f463b4e |
7
.gitignore
vendored
7
.gitignore
vendored
@ -1,6 +1,10 @@
|
||||
.deps
|
||||
.dirstamp
|
||||
.libs
|
||||
.*.swp
|
||||
*.log
|
||||
*.rej
|
||||
*.orig
|
||||
*.o
|
||||
*.lo
|
||||
*.la
|
||||
@ -29,6 +33,7 @@ control/prototype
|
||||
control/rpmmacros
|
||||
src/ipmievd
|
||||
src/ipmitool
|
||||
lib/ipmi_pen_list.inc.c
|
||||
doc/ipmievd.8
|
||||
doc/ipmitool.1
|
||||
cscope.out
|
||||
tags
|
||||
|
8
INSTALL
8
INSTALL
@ -22,12 +22,18 @@ project is tested automatically to build cleanly for the following
|
||||
- Ubuntu 16.04 Xenial
|
||||
- MacOS X 10.14 (Xcode 10.2)
|
||||
|
||||
For Ubuntu 16.04 it is recommended to do the following before building:
|
||||
$ sudo apt install automake gcc git libreadline-dev libssl-dev libsystemd-dev libtool make wget
|
||||
|
||||
For Fedora 31 it is recommended to do the following before building:
|
||||
$ sudo dnf install automake gcc git libtool make openssl-devel readline-devel systemd-devel wget
|
||||
|
||||
Basic Installation
|
||||
==================
|
||||
|
||||
Briefly, the followong shell command should configure, build, and
|
||||
install this package:
|
||||
`./bootstrap && ./configure && make && make install`
|
||||
`./bootstrap && ./configure && make && sudo make install`
|
||||
|
||||
The following more-detailed instructions are generic; see the
|
||||
`README' file for instructions specific to this package. Some
|
||||
|
28
Makefile.am
28
Makefile.am
@ -41,11 +41,37 @@ MAINTAINERCLEANFILES = Makefile.in aclocal.m4 configure configure-stamp \
|
||||
$(distdir).tar.gz $(distdir).tar.bz2
|
||||
|
||||
SUBDIRS = lib src include doc contrib control
|
||||
IANA_PEN = http://www.iana.org/assignments/enterprise-numbers
|
||||
|
||||
dist-hook:
|
||||
cp control/ipmitool.spec $(distdir)
|
||||
|
||||
install-data-local:
|
||||
.PHONY: install-pen-database
|
||||
|
||||
if DOWNLOAD
|
||||
|
||||
enterprise-numbers:
|
||||
@echo Downloading IANA PEN database...
|
||||
@$(DOWNLOAD) "$(IANA_PEN)" > tmpfile.$$PPID || {\
|
||||
echo "FAILED to download the IANA PEN database"; \
|
||||
rm tmpfile.$$PPID; \
|
||||
false; \
|
||||
}
|
||||
@mv tmpfile.$$PPID $@
|
||||
|
||||
install-pen-database: enterprise-numbers
|
||||
mkdir -m 755 -p $(DESTDIR)$(IANADIR)
|
||||
$(INSTALL_DATA) $< -t $(DESTDIR)$(IANADIR)/
|
||||
|
||||
else
|
||||
|
||||
install-pen-database:
|
||||
@echo "*** NOT installing the IANA PEN database."
|
||||
@echo "*** Don't know how to download it."
|
||||
|
||||
endif
|
||||
|
||||
install-data-local: install-pen-database
|
||||
mkdir -p $(DESTDIR)$(DOCDIR)
|
||||
$(INSTALL_DATA) $(DOCLIST) $(DESTDIR)$(DOCDIR)
|
||||
|
||||
|
2
README
2
README
@ -399,7 +399,7 @@ IPMItool homepage
|
||||
http://github.com/ipmitool/ipmitool
|
||||
|
||||
IPMItool manpage
|
||||
https://github.com/ipmitool/ipmitool/blob/master/doc/ipmitool.1
|
||||
https://github.com/ipmitool/ipmitool/blob/master/doc/ipmitool.1.in
|
||||
|
||||
Intelligent Platform Management Interface specification
|
||||
https://www.intel.com/content/www/us/en/servers/ipmi/ipmi-home.html
|
||||
|
71
configure.ac
71
configure.ac
@ -4,6 +4,7 @@ dnl
|
||||
m4_define([git_suffix], m4_esyscmd_s(./csv-revision))
|
||||
AC_INIT([ipmitool], [1.8.18git_suffix])
|
||||
AC_CONFIG_SRCDIR([src/ipmitool.c])
|
||||
AC_CONFIG_COMMANDS_PRE([export prefix=$prefix])
|
||||
AC_CANONICAL_SYSTEM
|
||||
AM_INIT_AUTOMAKE([foreign])
|
||||
AM_CONFIG_HEADER(config.h)
|
||||
@ -17,6 +18,8 @@ AC_PROG_LN_S
|
||||
AC_PROG_MAKE_SET
|
||||
AC_CHECK_PROG([RPMBUILD], [rpmbuild], [rpmbuild], [rpm])
|
||||
AC_CHECK_PROG([SED], [sed], [sed])
|
||||
AC_CHECK_PROG([WGET], [wget], [wget])
|
||||
AC_CHECK_PROG([CURL], [curl], [curl])
|
||||
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS([stdlib.h string.h sys/ioctl.h sys/stat.h unistd.h paths.h])
|
||||
@ -53,6 +56,23 @@ if test "x$exec_prefix" = "xNONE"; then
|
||||
exec_prefix="$prefix"
|
||||
fi
|
||||
|
||||
if test "x$WGET" = "x"; then
|
||||
if test "x$CURL" = "x"; then
|
||||
AC_MSG_WARN([** Neither wget nor curl could be found.])
|
||||
AC_MSG_WARN([** IANA PEN database will not be installed by `make install` !])
|
||||
else
|
||||
DOWNLOAD="$CURL -#"
|
||||
AM_CONDITIONAL([DOWNLOAD], [true])
|
||||
fi
|
||||
else
|
||||
DOWNLOAD="$WGET -c -nd -O -"
|
||||
AM_CONDITIONAL([DOWNLOAD], [true])
|
||||
fi
|
||||
|
||||
AC_MSG_WARN([** Download is:])
|
||||
AC_MSG_WARN($DOWNLOAD)
|
||||
AC_SUBST(DOWNLOAD, $DOWNLOAD)
|
||||
|
||||
dnl
|
||||
dnl set default option values
|
||||
dnl
|
||||
@ -596,30 +616,18 @@ fi
|
||||
|
||||
AC_SUBST(IPMITOOL_INTF_LIB)
|
||||
|
||||
if test "x$xenable_ipmishell" = "xyes"; then
|
||||
AC_SEARCH_LIBS([tgetent], [tinfo ncurses curses readline termcap])
|
||||
AC_SEARCH_LIBS([initscr], [ncurses curses], [have_curses=yes])
|
||||
AC_SEARCH_LIBS([readline], [readline edit], [have_readline=yes])
|
||||
if test "x$have_curses" != "xyes" || test "x$have_readline" != "xyes"; then
|
||||
xenable_ipmishell=no
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl check for readline library to enable ipmi shell
|
||||
AC_ARG_ENABLE([ipmishell],
|
||||
[AC_HELP_STRING([--enable-ipmishell],
|
||||
[enable IPMI shell interface [default=auto]])],
|
||||
[xenable_ipmishell=$enableval],
|
||||
[])
|
||||
|
||||
dnl check for readline library to enable ipmi shell
|
||||
if test "x$xenable_ipmishell" = "xyes"; then
|
||||
AC_SEARCH_LIBS([tgetent], [tinfo ncurses curses readline termcap])
|
||||
AC_SEARCH_LIBS([initscr], [ncurses curses], [have_curses=yes])
|
||||
AC_SEARCH_LIBS([readline], [readline edit], [have_readline=yes])
|
||||
if test "x$have_curses" != "xyes"; then
|
||||
AC_MSG_ERROR([** Unable to find curses required by ipmishell.])
|
||||
fi
|
||||
if test "x$have_readline" != "xyes"; then
|
||||
AC_MSG_ERROR([** Unable to find readline required by ipmishell.])
|
||||
xenable_ipmishell=no
|
||||
fi
|
||||
AC_DEFINE(HAVE_READLINE, [1], [Define to 1 if readline present.])
|
||||
fi
|
||||
@ -672,13 +680,13 @@ AC_TRY_COMPILE([],[
|
||||
)
|
||||
|
||||
dnl if no environment variable is set, set the default value for the default intf
|
||||
if test "${xenable_intf_open}" = "xyes"; then
|
||||
if test "${xenable_intf_open}" = "yes"; then
|
||||
DEFAULT_INTF_NO_ENV=open
|
||||
else dnl macOS does not build open interface, it defaults to lan
|
||||
DEFAULT_INTF_NO_ENV=lan
|
||||
fi
|
||||
dnl allow for a default interface to be set on configure
|
||||
AC_ARG_VAR(DEFAULT_INTF, [Set the default interface to use (default=${DEFAULT_INTF_NO_ENV})])
|
||||
AC_ARG_VAR(DEFAULT_INTF, [Set the default interface to use (default='open' if available, 'lan' otherwise)])
|
||||
|
||||
dnl set the default value for the default interface environment variable
|
||||
if test "x${DEFAULT_INTF}" == "x"; then
|
||||
@ -691,6 +699,32 @@ if test "x${!xdefault_intf_is_enabled}" != "xyes"; then
|
||||
AC_MSG_ERROR([** Cannot set ${DEFAULT_INTF} as default; ${DEFAULT_INTF} is not enabled. :${!xdefault_intf_is_enabled}:])
|
||||
fi
|
||||
|
||||
AC_ARG_VAR(IANADIR, [Configure the path to IANA PEN dictionary (default=DATAROOTDIR/misc)])
|
||||
AC_ARG_VAR(IANAUSERDIR, [Configure the path to IANA PEN dictionary wihtin the user's HOME directory (default=.local/usr/share/misc)])
|
||||
|
||||
if test "x${IANADIR}" == "x"; then
|
||||
echo Set IANA PEN dictionary search path to ${datarootdir}/misc
|
||||
IANADIR="${datarootdir}/misc"
|
||||
fi
|
||||
|
||||
if test "x${IANAUSERDIR}" == "x"; then
|
||||
IANAUSERDIR=".local/usr/share/misc"
|
||||
echo Set user\'s IANA PEN dictionary search path to ${IANAUSERDIR}
|
||||
fi
|
||||
|
||||
AH_TEMPLATE([IANADIR],[The path to system IANA PEN dictionary])
|
||||
AC_DEFINE_UNQUOTED(IANADIR, "`eval "echo ${IANADIR}"`", [])
|
||||
|
||||
AH_TEMPLATE([IANAUSERDIR],[The subpath to user IANA PEN dictionary within the user's HOME])
|
||||
AC_DEFINE_UNQUOTED(IANAUSERDIR, "`eval "echo ${IANAUSERDIR}"`", [])
|
||||
|
||||
AH_TEMPLATE([PATH_SEPARATOR], [The path separator string])
|
||||
#if defined _WIN32 || defined __CYGWIN__
|
||||
AC_DEFINE(PATH_SEPARATOR, "\\")
|
||||
#else
|
||||
AC_DEFINE(PATH_SEPARATOR, "/")
|
||||
#endif
|
||||
|
||||
dnl Generate files for build
|
||||
AC_CONFIG_FILES([Makefile
|
||||
doc/Makefile
|
||||
@ -717,6 +751,9 @@ AC_CONFIG_FILES([Makefile
|
||||
src/plugins/serial/Makefile
|
||||
src/plugins/dummy/Makefile])
|
||||
|
||||
AC_CONFIG_FILES([doc/ipmitool.1], [${SED} -i -e "s%\${prefix}%$prefix%" doc/ipmitool.1])
|
||||
AC_CONFIG_FILES([doc/ipmievd.8], [${SED} -i -e "s%\${prefix}%$prefix%" doc/ipmievd.8])
|
||||
|
||||
AC_OUTPUT
|
||||
|
||||
AC_MSG_RESULT([])
|
||||
|
@ -217,6 +217,16 @@ Reading Sensors...
|
||||
.br
|
||||
Waiting for Events...
|
||||
.br
|
||||
|
||||
.SH FILES
|
||||
.TP
|
||||
.B @IANADIR@/enterprise-numbers
|
||||
system IANA PEN registry taken from http://www.iana.org/assignments/enterprise-numbers
|
||||
.TP
|
||||
.B ~/@IANAUSERDIR@/enterprise-numbers
|
||||
user's override for the system IANA PEN registry, this file if it exists is loaded instead
|
||||
of the system registry (see above).
|
||||
|
||||
.SH "AUTHOR"
|
||||
Duncan Laurie <duncan@iceblink.org>
|
||||
.SH "SEE ALSO"
|
@ -259,11 +259,15 @@ system. It is thus recommended that IPMI password management only be done
|
||||
over IPMIv2.0 \fIlanplus\fP interface or the system interface on the
|
||||
local station.
|
||||
|
||||
For IPMI v1.5, the maximum password length is 16 characters.
|
||||
Passwords longer than 16 characters will be truncated.
|
||||
For IPMI v1.5, the maximum password length is 16 characters; longer
|
||||
passwords might be truncated or rejected by the server, or rejected
|
||||
by
|
||||
.BR ipmitool .
|
||||
|
||||
For IPMI v2.0, the maximum password length is 20 characters; longer
|
||||
passwords will be rejected by
|
||||
.BR ipmitool .
|
||||
|
||||
For IPMI v2.0, the maximum password length is 20 characters;
|
||||
longer passwords are truncated.
|
||||
.SH "COMMANDS"
|
||||
.TP
|
||||
\fIhelp\fP
|
||||
@ -473,36 +477,94 @@ Force boot into BIOS Setup.
|
||||
|
||||
Force boot from Floppy/primary removable media.
|
||||
.RE
|
||||
|
||||
.TP
|
||||
\fIbootmbox\fP \fIget\fP [text] [block <\fBblock#\fP>]
|
||||
|
||||
Read the Boot Initiator Mailbox in hex dump or in text mode.
|
||||
|
||||
By default the whole mailbox is read. If block number is specified,
|
||||
that particular block is read. For block 0 or when the whole
|
||||
mailbox is read, the Boot Initiator IANA Enterprise Number and
|
||||
the corresponding enterprise name are printed.
|
||||
|
||||
.TP
|
||||
\fIbootmbox\fP \fIset\fP text [block <\fBblock#\fP>] <\fBIANA_PEN\fP> "<\fBdata_string\fP>"
|
||||
|
||||
Write the specified <block> or the entire Boot Initiator Mailbox in text mode.
|
||||
It is required to specify a decimal IANA Enterprise Number recognized
|
||||
by the boot initiator on the target system. Refer to your target system
|
||||
manufacturer for details. The rest of the arguments are a text string.
|
||||
|
||||
When single block write is requested, the total length of <data> may not
|
||||
exceed 13 bytes for block 0, or 16 bytes otherwise.
|
||||
|
||||
.TP
|
||||
\fIbootmbox\fP \fIset\fP [block <\fBblock#\fP>] <\fBIANA_PEN\fP> <\fBdata_byte\fP> [<\fBdata_byte\fP> ...]
|
||||
|
||||
Same as above, but the arguments after IANA PEN are separate
|
||||
data byte values separated by spaces.
|
||||
|
||||
.TP
|
||||
\fIbootparam\fP
|
||||
\fIbootparam\fP \fIget\fP <\fBopt_id\fR> [<\fBopt_param\fR>]
|
||||
|
||||
Get value of system boot option number <\fBopt_id\fR>. Some boot
|
||||
options (e.g. option 7) can also take an optional numeric parameter.
|
||||
|
||||
.TP
|
||||
\fIbootparam\fP \fIset\fP bootflag <\fBdevice\fR> [options=...]
|
||||
|
||||
Set a boot flag. Valid devices are:
|
||||
|
||||
.RS
|
||||
.TP
|
||||
\fIforce_pxe\fP
|
||||
.IP \fIforce_pxe\fP
|
||||
|
||||
Force PXE boot
|
||||
.TP
|
||||
\fIforce_disk\fP
|
||||
.IP \fIforce_disk\fP
|
||||
|
||||
Force boot from default Hard-drive
|
||||
.TP
|
||||
\fIforce_safe\fP
|
||||
.IP \fIforce_safe\fP
|
||||
|
||||
Force boot from default Hard-drive, request Safe Mode
|
||||
.TP
|
||||
\fIforce_diag\fP
|
||||
.IP \fIforce_diag\fP
|
||||
|
||||
Force boot from Diagnostic Partition
|
||||
.TP
|
||||
\fIforce_cdrom\fP
|
||||
.IP \fIforce_cdrom\fP
|
||||
|
||||
Force boot from CD/DVD
|
||||
.TP
|
||||
\fIforce_bios\fP
|
||||
.IP \fIforce_bios\fP
|
||||
|
||||
Force boot into BIOS Setup
|
||||
|
||||
.PP
|
||||
Valid options are:
|
||||
|
||||
.IP \fIPEF\fP
|
||||
|
||||
Clear valid bit on reset/power cycle cause by PEF
|
||||
|
||||
.IP \fItimeout\fP
|
||||
|
||||
Automatically clear boot flag valid bit on timeout
|
||||
|
||||
.IP \fIwatchdog\fP
|
||||
|
||||
Clear valid bit on reset/power cycle cause by watchdog
|
||||
|
||||
.IP \fIreset\fP
|
||||
|
||||
Clear valid bit on push button reset/soft reset
|
||||
|
||||
.IP \fIpower\fP
|
||||
|
||||
Clear valid bit on power up via power push button or wake event
|
||||
.RE
|
||||
|
||||
.TP
|
||||
\fIselftest\fP
|
||||
|
||||
Get the chassis self-test results
|
||||
|
||||
.RE
|
||||
.TP
|
||||
\fIdcmi\fP
|
||||
@ -3468,12 +3530,13 @@ Displays a list of user information for all defined userids.
|
||||
|
||||
Sets the username associated with the given userid.
|
||||
.TP
|
||||
\fIpassword\fP <\fBuserid\fR> [<\fBpassword\fR>]
|
||||
\fIpassword\fP <\fBuserid\fR> [<\fBpassword\fR> [<\fB16|20\fR>]]
|
||||
.br
|
||||
|
||||
Sets the password for the given userid. If no password is given,
|
||||
the password is cleared (set to the NULL password). Be careful when
|
||||
removing passwords from administrator\-level accounts.
|
||||
removing passwords from administrator\-level accounts. If specified,
|
||||
16 or 20 determines the maximum password length.
|
||||
.RE
|
||||
.TP
|
||||
\fIdisable\fP <\fBuserid\fR>
|
||||
@ -3759,7 +3822,16 @@ Chassis Power is on
|
||||
> ipmitool \-I lan \-H 1.2.3.4 \-f passfile chassis power on
|
||||
.br
|
||||
Chassis Power Control: Up/On
|
||||
|
||||
|
||||
.SH FILES
|
||||
.TP
|
||||
.B @IANADIR@/enterprise-numbers
|
||||
system IANA PEN registry taken from http://www.iana.org/assignments/enterprise-numbers
|
||||
.TP
|
||||
.B ~/@IANAUSERDIR@/enterprise-numbers
|
||||
user's override for the system IANA PEN registry, this file if it exists is loaded instead
|
||||
of the system registry (see above).
|
||||
|
||||
.SH "AUTHORS"
|
||||
Originally written by Duncan Laurie <duncan@iceblink.org>.
|
||||
.br
|
@ -38,6 +38,7 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h> /* For free() */
|
||||
#include <stdbool.h>
|
||||
|
||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
|
||||
|
||||
@ -79,8 +80,12 @@ struct oemvalstr {
|
||||
const char * str;
|
||||
};
|
||||
|
||||
const char * val2str(uint16_t val, const struct valstr * vs);
|
||||
const char * oemval2str(uint32_t oem,uint16_t val, const struct oemvalstr * vs);
|
||||
const char *
|
||||
specific_val2str(uint32_t val,
|
||||
const struct valstr *specific,
|
||||
const struct valstr *generic);
|
||||
const char *val2str(uint32_t val, const struct valstr * vs);
|
||||
const char *oemval2str(uint32_t oem, uint32_t val, const struct oemvalstr * vs);
|
||||
|
||||
int str2double(const char * str, double * double_ptr);
|
||||
int str2long(const char * str, int64_t * lng_ptr);
|
||||
@ -92,6 +97,8 @@ int str2ushort(const char * str, uint16_t * ushrt_ptr);
|
||||
int str2char(const char * str, int8_t * chr_ptr);
|
||||
int str2uchar(const char * str, uint8_t * uchr_ptr);
|
||||
|
||||
bool args2buf(int argc, char *argv[], uint8_t *out, size_t len);
|
||||
|
||||
int eval_ccode(const int ccode);
|
||||
|
||||
int is_fru_id(const char *argv_ptr, uint8_t *fru_id_ptr);
|
||||
@ -99,7 +106,11 @@ int is_ipmi_channel_num(const char *argv_ptr, uint8_t *channel_ptr);
|
||||
int is_ipmi_user_id(const char *argv_ptr, uint8_t *ipmi_uid_ptr);
|
||||
int is_ipmi_user_priv_limit(const char *argv_ptr, uint8_t *ipmi_priv_limit_ptr);
|
||||
|
||||
uint16_t str2val(const char * str, const struct valstr * vs);
|
||||
uint32_t str2val32(const char *str, const struct valstr *vs);
|
||||
static inline uint16_t str2val(const char *str, const struct valstr *vs)
|
||||
{
|
||||
return (uint16_t)str2val32(str, 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);
|
||||
|
||||
@ -166,6 +177,13 @@ static inline uint32_t ipmi24toh(void *ipmi24)
|
||||
return h;
|
||||
}
|
||||
|
||||
static inline void htoipmi24(uint32_t h, uint8_t *ipmi)
|
||||
{
|
||||
ipmi[0] = h & 0xFF; /* LSB */
|
||||
ipmi[1] = (h >> 8) & 0xFF;
|
||||
ipmi[2] = (h >> 16) & 0xFF; /* MSB */
|
||||
}
|
||||
|
||||
static inline uint32_t ipmi32toh(void *ipmi32)
|
||||
{
|
||||
uint8_t *ipmi = ipmi32;
|
||||
|
@ -283,7 +283,7 @@ typedef enum IPMI_OEM {
|
||||
IPMI_OEM_MAGNUM = 5593,
|
||||
IPMI_OEM_TYAN = 6653,
|
||||
IPMI_OEM_QUANTA = 7244,
|
||||
IPMI_OEM_NEWISYS = 9237,
|
||||
IPMI_OEM_VIKING = 9237,
|
||||
IPMI_OEM_ADVANTECH = 10297,
|
||||
IPMI_OEM_FUJITSU_SIEMENS = 10368,
|
||||
IPMI_OEM_AVOCENT = 10418,
|
||||
|
@ -57,6 +57,28 @@
|
||||
#define IPMI_CHANNEL_SESSION_MULTI 0x80
|
||||
#define IPMI_CHANNEL_SESSION_BASED 0xC0
|
||||
|
||||
/* Fixed channel numbers as per Table 6-1 */
|
||||
typedef enum {
|
||||
CH_PRIMARY_IPMB,
|
||||
CH_IMP_SPECIFIC_1,
|
||||
CH_IMP_SPECIFIC_2,
|
||||
CH_IMP_SPECIFIC_3,
|
||||
CH_IMP_SPECIFIC_4,
|
||||
CH_IMP_SPECIFIC_5,
|
||||
CH_IMP_SPECIFIC_6,
|
||||
CH_IMP_SPECIFIC_7,
|
||||
CH_IMP_SPECIFIC_8,
|
||||
CH_IMP_SPECIFIC_9,
|
||||
CH_IMP_SPECIFIC_A,
|
||||
CH_IMP_SPECIFIC_B,
|
||||
CH_RSVD1,
|
||||
CH_RSVD2,
|
||||
CH_CURRENT,
|
||||
CH_SYSTEM,
|
||||
CH_TOTAL,
|
||||
CH_UNKNOWN = UINT8_MAX
|
||||
} ipmi_channel_num_t;
|
||||
|
||||
/* (22.24) Get Channel Info */
|
||||
struct channel_info_t {
|
||||
uint8_t channel;
|
||||
@ -189,7 +211,8 @@ int _ipmi_set_channel_access(struct ipmi_intf *intf,
|
||||
uint8_t privilege_option);
|
||||
|
||||
uint8_t ipmi_get_channel_medium(struct ipmi_intf * intf, uint8_t channel);
|
||||
uint8_t ipmi_current_channel_medium(struct ipmi_intf * intf);
|
||||
void ipmi_current_channel_info(struct ipmi_intf *intf,
|
||||
struct channel_info_t *chinfo);
|
||||
int ipmi_channel_main(struct ipmi_intf * intf, int argc, char ** argv);
|
||||
int ipmi_get_channel_auth_cap(struct ipmi_intf * intf,
|
||||
uint8_t channel, uint8_t priv);
|
||||
|
@ -61,6 +61,33 @@ struct platform_event_msg {
|
||||
#pragma pack(0)
|
||||
#endif
|
||||
|
||||
/* See IPMI 2.0 Specification, Appendix G, Table G-1, "Event Commands" */
|
||||
typedef enum {
|
||||
IPMI_CMD_SET_EVENT_RCVR = 0,
|
||||
IPMI_CMD_GET_EVENT_RCVR,
|
||||
IPMI_CMD_PLATFORM_EVENT
|
||||
} ipmi_event_cmd_t;
|
||||
|
||||
typedef enum {
|
||||
PLATFORM_EVENT_DATA_LEN_NON_SI = sizeof(struct platform_event_msg),
|
||||
PLATFORM_EVENT_DATA_LEN_SI, /* System interfaces require generator ID */
|
||||
PLATFORM_EVENT_DATA_LEN_MAX = PLATFORM_EVENT_DATA_LEN_SI
|
||||
} ipmi_platform_event_data_len_t;
|
||||
|
||||
/* See Table 5-4 */
|
||||
typedef enum {
|
||||
EVENT_SWID_BIOS_BASE = 0x00, /* BIOS */
|
||||
EVENT_SWID_SMI_BASE = 0x10, /* SMI Handler */
|
||||
EVENT_SWID_SMS_BASE = 0x20, /* System Management Software */
|
||||
EVENT_SWID_OEM_BASE = 0x30, /* OEM */
|
||||
EVENT_SWID_REMOTE_CONSOLE_BASE = 0x40, /* Remote Console SW */
|
||||
EVENT_SWID_TERMINAL_MODE_BASE = 0x47 /* Terminal Mode RC SW */
|
||||
} ipmi_event_swid_t;
|
||||
#define EVENT_SWID(base, index) ((EVENT_SWID_##base##_BASE + index) & 0x7F)
|
||||
|
||||
/* See Figure 29-2, Table 32-1 */
|
||||
#define EVENT_GENERATOR(base, index) (EVENT_SWID(base,index) << 1 | 1)
|
||||
|
||||
int ipmi_event_main(struct ipmi_intf *, int, char **);
|
||||
|
||||
#endif /*IPMI_EVENT_H*/
|
||||
|
@ -241,6 +241,9 @@ struct ipmi_intf {
|
||||
void (*set_max_response_data_size)(struct ipmi_intf * intf, uint16_t size);
|
||||
};
|
||||
|
||||
uint16_t ipmi_intf_get_max_request_data_size(struct ipmi_intf *intf);
|
||||
uint16_t ipmi_intf_get_max_response_data_size(struct ipmi_intf *intf);
|
||||
|
||||
struct ipmi_intf * ipmi_intf_load(char * name);
|
||||
void ipmi_intf_print(struct ipmi_intf_support * intflist);
|
||||
|
||||
|
@ -104,6 +104,24 @@ enum {
|
||||
#define GET_SENSOR_READING 0x2d
|
||||
#define GET_SENSOR_TYPE 0x2f
|
||||
|
||||
/*
|
||||
* IPMI Specification limits the length of the ID string to 16 bytes for
|
||||
* SDR records, although the ID type/length code may contain a number up
|
||||
* to 31 (0x1F). See IPMI 2.0 Specification Tables 43-6 through 43-8.
|
||||
*/
|
||||
#define SDR_TYPECODE_LEN_MASK 0x1f
|
||||
#define SDR_ID_STRING_MAX 16
|
||||
#define SDR_ID_STRLEN_BYTYPE(typelen) \
|
||||
((size_t)__max(typelen & SDR_TYPECODE_LEN_MASK, SDR_ID_STRING_MAX))
|
||||
#define SDR_ID_STRLEN(sdr) SDR_ID_STRLEN_BYTYPE((sdr)->id_code)
|
||||
|
||||
#define SDR_ID_TO_CSTRING(cstring, sdr) \
|
||||
do { \
|
||||
memset((cstring), 0, sizeof(cstring)); \
|
||||
snprintf((cstring), sizeof(cstring), "%.*s", \
|
||||
SDR_ID_STRLEN(sdr), (sdr)->id_string); \
|
||||
} while(0)
|
||||
|
||||
#ifdef HAVE_PRAGMA_PACK
|
||||
#pragma pack(1)
|
||||
#endif
|
||||
@ -466,7 +484,7 @@ struct sdr_record_compact_sensor {
|
||||
uint8_t __reserved[3];
|
||||
uint8_t oem; /* reserved for OEM use */
|
||||
uint8_t id_code; /* sensor ID string type/length code */
|
||||
uint8_t id_string[16]; /* sensor ID string bytes, only if id_code != 0 */
|
||||
uint8_t id_string[SDR_ID_STRING_MAX]; /* sensor ID string bytes */
|
||||
} ATTRIBUTE_PACKING;
|
||||
#ifdef HAVE_PRAGMA_PACK
|
||||
#pragma pack(0)
|
||||
@ -517,7 +535,7 @@ struct sdr_record_eventonly_sensor {
|
||||
uint8_t __reserved;
|
||||
uint8_t oem; /* reserved for OEM use */
|
||||
uint8_t id_code; /* sensor ID string type/length code */
|
||||
uint8_t id_string[16]; /* sensor ID string bytes, only if id_code != 0 */
|
||||
uint8_t id_string[SDR_ID_STRING_MAX]; /* sensor ID string bytes */
|
||||
|
||||
} ATTRIBUTE_PACKING;
|
||||
#ifdef HAVE_PRAGMA_PACK
|
||||
@ -587,7 +605,7 @@ struct sdr_record_full_sensor {
|
||||
uint8_t __reserved[2];
|
||||
uint8_t oem; /* reserved for OEM use */
|
||||
uint8_t id_code; /* sensor ID string type/length code */
|
||||
uint8_t id_string[16]; /* sensor ID string bytes, only if id_code != 0 */
|
||||
uint8_t id_string[SDR_ID_STRING_MAX]; /* sensor ID string bytes */
|
||||
} ATTRIBUTE_PACKING;
|
||||
#ifdef HAVE_PRAGMA_PACK
|
||||
#pragma pack(0)
|
||||
@ -619,7 +637,7 @@ struct sdr_record_mc_locator {
|
||||
struct entity_id entity;
|
||||
uint8_t oem;
|
||||
uint8_t id_code;
|
||||
uint8_t id_string[16];
|
||||
uint8_t id_string[SDR_ID_STRING_MAX];
|
||||
} ATTRIBUTE_PACKING;
|
||||
#ifdef HAVE_PRAGMA_PACK
|
||||
#pragma pack(0)
|
||||
@ -652,7 +670,7 @@ struct sdr_record_fru_locator {
|
||||
struct entity_id entity;
|
||||
uint8_t oem;
|
||||
uint8_t id_code;
|
||||
uint8_t id_string[16];
|
||||
uint8_t id_string[SDR_ID_STRING_MAX];
|
||||
} ATTRIBUTE_PACKING;
|
||||
#ifdef HAVE_PRAGMA_PACK
|
||||
#pragma pack(0)
|
||||
@ -686,7 +704,7 @@ struct sdr_record_generic_locator {
|
||||
struct entity_id entity;
|
||||
uint8_t oem;
|
||||
uint8_t id_code;
|
||||
uint8_t id_string[16];
|
||||
uint8_t id_string[SDR_ID_STRING_MAX];
|
||||
} ATTRIBUTE_PACKING;
|
||||
#ifdef HAVE_PRAGMA_PACK
|
||||
#pragma pack(0)
|
||||
@ -800,9 +818,12 @@ struct sdr_record_list {
|
||||
#define SENSOR_TYPE_MAX 0x2C
|
||||
|
||||
struct sensor_reading {
|
||||
char s_id[17]; /* name of the sensor */
|
||||
struct sdr_record_full_sensor *full;
|
||||
struct sdr_record_compact_sensor *compact;
|
||||
char s_id[SDR_ID_STRING_MAX + 1]; /* sensor name, null-terminated */
|
||||
union {
|
||||
struct sdr_record_full_sensor *full;
|
||||
struct sdr_record_compact_sensor *compact;
|
||||
void *raw;
|
||||
};
|
||||
uint8_t s_reading_valid; /* read value valididity */
|
||||
uint8_t s_scanning_disabled; /* read of value disabled */
|
||||
uint8_t s_reading_unavailable; /* read value unavailable */
|
||||
@ -848,7 +869,7 @@ uint8_t *ipmi_sdr_get_record(struct ipmi_intf *intf, struct sdr_get_rs *header,
|
||||
void ipmi_sdr_end(struct ipmi_sdr_iterator *i);
|
||||
int ipmi_sdr_print_sdr(struct ipmi_intf *intf, uint8_t type);
|
||||
|
||||
int ipmi_sdr_print_name_from_rawentry(uint16_t id, uint8_t type,uint8_t * raw);
|
||||
int sdr_get_name_from_rawentry(uint8_t type, void *raw, char *buf, size_t len);
|
||||
int ipmi_sdr_print_rawentry(struct ipmi_intf *intf, uint8_t type, uint8_t * raw,
|
||||
int len);
|
||||
int ipmi_sdr_print_listentry(struct ipmi_intf *intf,
|
||||
|
@ -679,7 +679,7 @@ void ipmi_sel_print_extended_entry_verbose(struct ipmi_intf * intf, struct sel_e
|
||||
void ipmi_get_event_desc(struct ipmi_intf * intf, struct sel_event_record * rec, char ** desc);
|
||||
const char * ipmi_get_sensor_type(struct ipmi_intf *intf, uint8_t code);
|
||||
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);
|
||||
char * get_viking_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);
|
||||
int ipmi_sel_oem_init(const char * filename);
|
||||
|
@ -53,8 +53,10 @@ 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[];
|
||||
extern const struct valstr ipmi_user_enable_status_vals[];
|
||||
extern const struct valstr *ipmi_oem_info;
|
||||
int ipmi_oem_info_init();
|
||||
void ipmi_oem_info_free();
|
||||
|
||||
extern const struct valstr picmg_frucontrol_vals[];
|
||||
extern const struct valstr picmg_clk_family_vals[];
|
||||
|
@ -31,7 +31,6 @@
|
||||
AUTOMAKE_OPTIONS = subdir-objects
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/include
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
PEN_LIST = $(srcdir)/ipmi_pen_list.inc.c
|
||||
|
||||
noinst_LTLIBRARIES = libipmitool.la
|
||||
libipmitool_la_SOURCES = helper.c ipmi_sdr.c ipmi_sel.c ipmi_sol.c ipmi_pef.c \
|
||||
@ -49,8 +48,3 @@ libipmitool_la_LDFLAGS = -export-dynamic
|
||||
libipmitool_la_LIBADD = -lm
|
||||
libipmitool_la_DEPENDENCIES =
|
||||
|
||||
$(PEN_LIST):
|
||||
$(srcdir)/create_pen_list $(PEN_LIST)
|
||||
|
||||
ipmi_strings.lo: $(PEN_LIST)
|
||||
|
||||
|
@ -1,77 +0,0 @@
|
||||
#!/bin/bash
|
||||
# vi: set ts=2 sw=2 et :
|
||||
#
|
||||
# IANA PEN List generator
|
||||
#
|
||||
# This script takes the official IANA PEN registry and generates
|
||||
# a C language output for inclusion into ipmi_strings.c
|
||||
#
|
||||
# Copyright (c) 2018 Alexander Amelkin <alexander@amelkin.msk.ru>
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions 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.
|
||||
#
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from this
|
||||
# software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
|
||||
OUTFILE=$1
|
||||
PENLIST_URL=https://www.iana.org/assignments/enterprise-numbers/enterprise-numbers
|
||||
|
||||
if [ -z "$OUTFILE" ]; then
|
||||
echo $0: Must specify output file
|
||||
exit
|
||||
fi
|
||||
|
||||
parse_pen_list() {
|
||||
iconv -f utf8 -t ascii//TRANSLIT//IGNORE \
|
||||
| awk '
|
||||
/^[0-9]+/ {
|
||||
if(PEN) {
|
||||
print "{ " PEN ", \"" ENTERPRISE "\" },"
|
||||
}
|
||||
PEN=$1
|
||||
}
|
||||
|
||||
/^ [[:alnum:]]/ {
|
||||
# Remove leading spaces
|
||||
sub(/^[[:space:]]+/,"")
|
||||
# Remove question marks (Chinese characters after iconv)
|
||||
gsub(/\?/,"");
|
||||
# Remove non-printable characters
|
||||
gsub(/[^[:print:]]/,"");
|
||||
# Escape slashes and double quotes
|
||||
gsub(/["\\]/,"\\\\&")
|
||||
ENTERPRISE=$0;
|
||||
}
|
||||
|
||||
END {
|
||||
if(PEN) {
|
||||
print "{ " PEN ", \"" ENTERPRISE "\" },"
|
||||
}
|
||||
}'
|
||||
}
|
||||
|
||||
echo "Generating IANA PEN list..."
|
||||
curl -# "$PENLIST_URL" | parse_pen_list > "$OUTFILE"
|
@ -1621,7 +1621,7 @@ ipmi_spd_print_fru(struct ipmi_intf * intf, uint8_t id)
|
||||
struct ipmi_rq req;
|
||||
struct fru_info fru;
|
||||
uint8_t *spd_data, msg_data[4];
|
||||
int len, offset;
|
||||
uint32_t len, offset;
|
||||
|
||||
msg_data[0] = id;
|
||||
|
||||
@ -1697,6 +1697,13 @@ ipmi_spd_print_fru(struct ipmi_intf * intf, uint8_t id)
|
||||
}
|
||||
|
||||
len = rsp->data[0];
|
||||
if(rsp->data_len < 1
|
||||
|| len > rsp->data_len - 1
|
||||
|| len > fru.size - offset)
|
||||
{
|
||||
printf(" Not enough buffer size");
|
||||
return -1;
|
||||
}
|
||||
memcpy(&spd_data[offset], rsp->data + 1, len);
|
||||
offset += len;
|
||||
} while (offset < fru.size);
|
||||
|
107
lib/helper.c
107
lib/helper.c
@ -319,26 +319,74 @@ mac2str(const uint8_t *buf)
|
||||
return buf2str_extended(buf, 6, ":");
|
||||
}
|
||||
|
||||
const char * val2str(uint16_t val, const struct valstr *vs)
|
||||
/**
|
||||
* Find the index of value in a valstr array
|
||||
*
|
||||
* @param[in] val The value to search for
|
||||
* @param[in] vs The valstr array to search in
|
||||
* @return >=0 The index into \p vs
|
||||
* @return -1 Error: value \p val was not found in \p vs
|
||||
*/
|
||||
static
|
||||
inline
|
||||
off_t find_val_idx(uint32_t val, const struct valstr *vs)
|
||||
{
|
||||
static char un_str[32];
|
||||
int i;
|
||||
|
||||
for (i = 0; vs[i].str; i++) {
|
||||
if (vs[i].val == val)
|
||||
return vs[i].str;
|
||||
if (vs) {
|
||||
for (off_t i = 0; vs[i].str; ++i) {
|
||||
if (vs[i].val == val) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a statically allocated 'Unknown' string for the provided value.
|
||||
* The function is not thread-safe (as most of ipmitool).
|
||||
*
|
||||
* @param[in] val The value to put into the string
|
||||
* @returns A pointer to a statically allocated string
|
||||
*/
|
||||
static
|
||||
inline
|
||||
const char *unknown_val_str(uint32_t val)
|
||||
{
|
||||
static char un_str[32];
|
||||
memset(un_str, 0, 32);
|
||||
snprintf(un_str, 32, "Unknown (0x%02X)", val);
|
||||
|
||||
return un_str;
|
||||
}
|
||||
|
||||
const char * oemval2str(uint32_t oem, uint16_t val,
|
||||
const struct oemvalstr *vs)
|
||||
const char *
|
||||
specific_val2str(uint32_t val,
|
||||
const struct valstr *specific,
|
||||
const struct valstr *generic)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (0 <= (i = find_val_idx(val, specific))) {
|
||||
return specific[i].str;
|
||||
}
|
||||
|
||||
if (0 <= (i = find_val_idx(val, generic))) {
|
||||
return generic[i].str;
|
||||
}
|
||||
|
||||
return unknown_val_str(val);
|
||||
}
|
||||
|
||||
const char *val2str(uint32_t val, const struct valstr *vs)
|
||||
{
|
||||
return specific_val2str(val, NULL, vs);
|
||||
}
|
||||
|
||||
|
||||
const char *oemval2str(uint32_t oem, uint32_t val,
|
||||
const struct oemvalstr *vs)
|
||||
{
|
||||
static char un_str[32];
|
||||
int i;
|
||||
|
||||
for (i = 0; vs[i].oem != 0xffffff && vs[i].str; i++) {
|
||||
@ -349,10 +397,7 @@ const char * oemval2str(uint32_t oem, uint16_t val,
|
||||
}
|
||||
}
|
||||
|
||||
memset(un_str, 0, 32);
|
||||
snprintf(un_str, 32, "Unknown (0x%X)", val);
|
||||
|
||||
return un_str;
|
||||
return unknown_val_str(val);
|
||||
}
|
||||
|
||||
/* str2double - safely convert string to double
|
||||
@ -597,7 +642,7 @@ int str2uchar(const char * str, uint8_t * uchr_ptr)
|
||||
return 0;
|
||||
} /* str2uchar(...) */
|
||||
|
||||
uint16_t str2val(const char *str, const struct valstr *vs)
|
||||
uint32_t str2val32(const char *str, const struct valstr *vs)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -1080,3 +1125,35 @@ ipmi_get_oem_id(struct ipmi_intf *intf)
|
||||
|
||||
return oem_id;
|
||||
}
|
||||
|
||||
/** Parse command line arguments as numeric byte values (dec or hex)
|
||||
* and store them in a \p len sized buffer \p out.
|
||||
*
|
||||
* @param[in] argc Number of arguments
|
||||
* @param[in] argv Array of arguments
|
||||
* @param[out] out The output buffer
|
||||
* @param[in] len Length of the output buffer in bytes (no null-termination
|
||||
* is assumed, the input data is treated as raw byte values,
|
||||
* not as a string.
|
||||
*
|
||||
* @returns A success status indicator
|
||||
* @return false Error
|
||||
* @return true Success
|
||||
*/
|
||||
bool
|
||||
args2buf(int argc, char *argv[], uint8_t *out, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < len && i < (size_t)argc; ++i) {
|
||||
uint8_t byte;
|
||||
|
||||
if (str2uchar(argv[i], &byte)) {
|
||||
lprintf(LOG_ERR, "Bad byte value: %s", argv[i]);
|
||||
return false;
|
||||
}
|
||||
|
||||
out[i] = byte;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -244,10 +244,28 @@ ipmi_1_5_authtypes(uint8_t n)
|
||||
return supportedTypes;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
ipmi_current_channel_medium(struct ipmi_intf *intf)
|
||||
void
|
||||
ipmi_current_channel_info(struct ipmi_intf *intf,
|
||||
struct channel_info_t *chinfo)
|
||||
{
|
||||
return ipmi_get_channel_medium(intf, 0xE);
|
||||
int ccode = 0;
|
||||
|
||||
chinfo->channel = CH_CURRENT;
|
||||
ccode = _ipmi_get_channel_info(intf, chinfo);
|
||||
if (ccode) {
|
||||
if (ccode != IPMI_CC_INV_DATA_FIELD_IN_REQ) {
|
||||
if (ccode > 0) {
|
||||
lprintf(LOG_ERR, "Get Channel Info command failed: %s",
|
||||
val2str(ccode, completion_code_vals));
|
||||
}
|
||||
else {
|
||||
eval_ccode(ccode);
|
||||
}
|
||||
}
|
||||
chinfo->channel = CH_UNKNOWN;
|
||||
chinfo->medium = IPMI_CHANNEL_MEDIUM_RESERVED;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -480,7 +498,10 @@ ipmi_get_channel_cipher_suites(struct ipmi_intf *intf,
|
||||
lprintf(LOG_ERR, "Unable to Get Channel Cipher Suites");
|
||||
return -1;
|
||||
}
|
||||
if (rsp->ccode || rsp->data_len < 1) {
|
||||
if (rsp->ccode
|
||||
|| rsp->data_len < 1
|
||||
|| rsp->data_len > sizeof(uint8_t) + MAX_CIPHER_SUITE_DATA_LEN)
|
||||
{
|
||||
lprintf(LOG_ERR, "Get Channel Cipher Suites failed: %s",
|
||||
val2str(rsp->ccode, completion_code_vals));
|
||||
return -1;
|
||||
@ -684,13 +705,16 @@ ipmi_get_channel_medium(struct ipmi_intf *intf, uint8_t channel)
|
||||
|
||||
channel_info.channel = channel;
|
||||
ccode = _ipmi_get_channel_info(intf, &channel_info);
|
||||
if (ccode == 0xCC) {
|
||||
return IPMI_CHANNEL_MEDIUM_RESERVED;
|
||||
} else if (ccode < 0 && eval_ccode(ccode) != 0) {
|
||||
return 0;
|
||||
} else if (ccode) {
|
||||
lprintf(LOG_ERR, "Get Channel Info command failed: %s",
|
||||
val2str(ccode, completion_code_vals));
|
||||
if (ccode) {
|
||||
if (ccode != IPMI_CC_INV_DATA_FIELD_IN_REQ) {
|
||||
if (ccode > 0) {
|
||||
lprintf(LOG_ERR, "Get Channel Info command failed: %s",
|
||||
val2str(ccode, completion_code_vals));
|
||||
}
|
||||
else {
|
||||
eval_ccode(ccode);
|
||||
}
|
||||
}
|
||||
return IPMI_CHANNEL_MEDIUM_RESERVED;
|
||||
}
|
||||
lprintf(LOG_DEBUG, "Channel type: %s",
|
||||
|
1248
lib/ipmi_chassis.c
1248
lib/ipmi_chassis.c
File diff suppressed because it is too large
Load Diff
@ -450,7 +450,7 @@ const struct dcmi_cmd nm_policy_options[] = {
|
||||
{ 0x02, "disable", "" },
|
||||
{ 0x03, "domain", "" },
|
||||
{ 0x04, "inlet", "inlet air temp full limiting (SCRAM)" },
|
||||
{ 0x06, "correction" "auto, soft, hard" },
|
||||
{ 0x06, "correction","auto, soft, hard" },
|
||||
{ 0x08, "power", "power limit in watts" },
|
||||
{ 0x09, "trig_lim", "time to send alert" },
|
||||
{ 0x0A, "stats", "moving window averaging time" },
|
||||
|
121
lib/ipmi_event.c
121
lib/ipmi_event.c
@ -52,6 +52,14 @@
|
||||
#include <ipmitool/ipmi_event.h>
|
||||
#include <ipmitool/ipmi_sdr.h>
|
||||
|
||||
static
|
||||
inline
|
||||
bool
|
||||
is_system(const struct channel_info_t *chinfo)
|
||||
{
|
||||
return (IPMI_CHANNEL_MEDIUM_SYSTEM == chinfo->medium
|
||||
|| CH_SYSTEM == chinfo->channel);
|
||||
}
|
||||
|
||||
static void
|
||||
ipmi_event_msg_print(struct ipmi_intf * intf, struct platform_event_msg * pmsg)
|
||||
@ -61,7 +69,8 @@ ipmi_event_msg_print(struct ipmi_intf * intf, struct platform_event_msg * pmsg)
|
||||
memset(&sel_event, 0, sizeof(struct sel_event_record));
|
||||
|
||||
sel_event.record_id = 0;
|
||||
sel_event.sel_type.standard_type.gen_id = 2;
|
||||
htoipmi16(EVENT_GENERATOR(SMS, 0),
|
||||
(void *)&sel_event.sel_type.standard_type.gen_id);
|
||||
|
||||
sel_event.sel_type.standard_type.evm_rev = pmsg->evm_rev;
|
||||
sel_event.sel_type.standard_type.sensor_type = pmsg->sensor_type;
|
||||
@ -83,28 +92,34 @@ ipmi_send_platform_event(struct ipmi_intf * intf, struct platform_event_msg * em
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
uint8_t rqdata[8];
|
||||
uint8_t chmed;
|
||||
uint8_t rqdata[PLATFORM_EVENT_DATA_LEN_MAX];
|
||||
uint8_t *rqdata_start = rqdata;
|
||||
struct channel_info_t chinfo;
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
memset(rqdata, 0, 8);
|
||||
memset(rqdata, 0, sizeof(rqdata));
|
||||
|
||||
req.msg.netfn = IPMI_NETFN_SE;
|
||||
req.msg.cmd = 0x02;
|
||||
req.msg.cmd = IPMI_CMD_PLATFORM_EVENT;
|
||||
req.msg.data = rqdata;
|
||||
req.msg.data_len = PLATFORM_EVENT_DATA_LEN_NON_SI;
|
||||
|
||||
chmed = ipmi_current_channel_medium(intf);
|
||||
if (chmed == IPMI_CHANNEL_MEDIUM_SYSTEM) {
|
||||
/* system interface, need extra generator ID */
|
||||
req.msg.data_len = 8;
|
||||
rqdata[0] = 0x41; // As per Fig. 29-2 and Table 5-4
|
||||
memcpy(rqdata+1, emsg, sizeof(struct platform_event_msg));
|
||||
ipmi_current_channel_info(intf, &chinfo);
|
||||
if (chinfo.channel == CH_UNKNOWN) {
|
||||
lprintf(LOG_ERR, "Failed to send the platform event "
|
||||
"via an unknown channel");
|
||||
return -3;
|
||||
}
|
||||
else {
|
||||
req.msg.data_len = 7;
|
||||
memcpy(rqdata, emsg, sizeof(struct platform_event_msg));
|
||||
|
||||
if (is_system(&chinfo)) {
|
||||
/* system interface, need extra generator ID, see Fig. 29-2 */
|
||||
req.msg.data_len = PLATFORM_EVENT_DATA_LEN_SI;
|
||||
rqdata[0] = EVENT_GENERATOR(SMS, 0);
|
||||
rqdata_start++;
|
||||
}
|
||||
|
||||
memcpy(rqdata_start, emsg, sizeof(struct platform_event_msg));
|
||||
|
||||
ipmi_event_msg_print(intf, emsg);
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
@ -484,43 +499,30 @@ static int
|
||||
ipmi_event_fromfile(struct ipmi_intf * intf, char * file)
|
||||
{
|
||||
FILE * fp;
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
struct sel_event_record sel_event;
|
||||
uint8_t rqdata[8];
|
||||
/* For ease of filling in from file data */
|
||||
union {
|
||||
struct platform_event_msg emsg;
|
||||
uint8_t bytes[sizeof(struct platform_event_msg)];
|
||||
} __attribute__ ((packed)) rqdata;
|
||||
char buf[1024];
|
||||
char * ptr, * tok;
|
||||
int i, j;
|
||||
uint8_t chmed;
|
||||
int rc = 0;
|
||||
|
||||
if (!file)
|
||||
return -1;
|
||||
|
||||
memset(rqdata, 0, 8);
|
||||
|
||||
/* setup Platform Event Message command */
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.msg.netfn = IPMI_NETFN_SE;
|
||||
req.msg.cmd = 0x02;
|
||||
req.msg.data = rqdata;
|
||||
req.msg.data_len = 7;
|
||||
|
||||
chmed = ipmi_current_channel_medium(intf);
|
||||
if (chmed == IPMI_CHANNEL_MEDIUM_SYSTEM) {
|
||||
/* system interface, need extra generator ID */
|
||||
rqdata[0] = 0x41; // As per Fig. 29-2 and Table 5-4
|
||||
req.msg.data_len = 8;
|
||||
}
|
||||
|
||||
fp = ipmi_open_file_read(file);
|
||||
if (!fp)
|
||||
return -1;
|
||||
|
||||
while (feof(fp) == 0) {
|
||||
size_t count = 0;
|
||||
if (!fgets(buf, 1024, fp))
|
||||
continue;
|
||||
|
||||
/* Each line is a new event */
|
||||
memset(&rqdata, 0, sizeof(rqdata));
|
||||
|
||||
/* clip off optional comment tail indicated by # */
|
||||
ptr = strchr(buf, '#');
|
||||
if (ptr)
|
||||
@ -540,49 +542,28 @@ ipmi_event_fromfile(struct ipmi_intf * intf, char * file)
|
||||
|
||||
/* parse the event, 7 bytes with optional comment */
|
||||
/* 0x00 0x00 0x00 0x00 0x00 0x00 0x00 # event */
|
||||
i = 0;
|
||||
tok = strtok(ptr, " ");
|
||||
while (tok) {
|
||||
if (i == 7)
|
||||
if (count == sizeof(struct platform_event_msg))
|
||||
break;
|
||||
j = i++;
|
||||
if (chmed == IPMI_CHANNEL_MEDIUM_SYSTEM)
|
||||
j++;
|
||||
rqdata[j] = (uint8_t)strtol(tok, NULL, 0);
|
||||
if (0 > str2uchar(tok, &rqdata.bytes[count])) {
|
||||
lprintf(LOG_ERR, "Invalid token in file: [%s]", tok);
|
||||
rc = -1;
|
||||
break;
|
||||
}
|
||||
tok = strtok(NULL, " ");
|
||||
++count;
|
||||
}
|
||||
if (i < 7) {
|
||||
if (count < sizeof(struct platform_event_msg)) {
|
||||
lprintf(LOG_ERR, "Invalid Event: %s",
|
||||
buf2str(rqdata, sizeof(rqdata)));
|
||||
buf2str(rqdata.bytes, sizeof(rqdata.bytes)));
|
||||
continue;
|
||||
}
|
||||
|
||||
memset(&sel_event, 0, sizeof(struct sel_event_record));
|
||||
sel_event.record_id = 0;
|
||||
sel_event.sel_type.standard_type.gen_id = 2;
|
||||
|
||||
j = (chmed == IPMI_CHANNEL_MEDIUM_SYSTEM) ? 1 : 0;
|
||||
sel_event.sel_type.standard_type.evm_rev = rqdata[j++];
|
||||
sel_event.sel_type.standard_type.sensor_type = rqdata[j++];
|
||||
sel_event.sel_type.standard_type.sensor_num = rqdata[j++];
|
||||
sel_event.sel_type.standard_type.event_type = rqdata[j] & 0x7f;
|
||||
sel_event.sel_type.standard_type.event_dir = (rqdata[j++] & 0x80) >> 7;
|
||||
sel_event.sel_type.standard_type.event_data[0] = rqdata[j++];
|
||||
sel_event.sel_type.standard_type.event_data[1] = rqdata[j++];
|
||||
sel_event.sel_type.standard_type.event_data[2] = rqdata[j++];
|
||||
|
||||
ipmi_sel_print_std_entry(intf, &sel_event);
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (!rsp) {
|
||||
lprintf(LOG_ERR, "Platform Event Message command failed");
|
||||
rc = -1;
|
||||
}
|
||||
else if (rsp->ccode) {
|
||||
lprintf(LOG_ERR, "Platform Event Message command failed: %s",
|
||||
val2str(rsp->ccode, completion_code_vals));
|
||||
rc = -1;
|
||||
}
|
||||
/* Now actually send it, failures will be logged by the sender */
|
||||
rc = ipmi_send_platform_event(intf, &rqdata.emsg);
|
||||
if (IPMI_CC_OK != rc)
|
||||
break;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
@ -111,12 +111,6 @@ static inline bool fru_cc_rq2big(int code) {
|
||||
int
|
||||
ipmi_spd_print_fru(struct ipmi_intf * intf, uint8_t id);
|
||||
|
||||
/* From src/plugins/ipmi_intf.c: */
|
||||
void
|
||||
ipmi_intf_set_max_request_data_size(struct ipmi_intf * intf, uint16_t size);
|
||||
void
|
||||
ipmi_intf_set_max_response_data_size(struct ipmi_intf * intf, uint16_t size);
|
||||
|
||||
extern int verbose;
|
||||
|
||||
static void ipmi_fru_read_to_bin(struct ipmi_intf * intf, char * pFileName, uint8_t fruId);
|
||||
@ -669,7 +663,10 @@ int
|
||||
read_fru_area(struct ipmi_intf * intf, struct fru_info *fru, uint8_t id,
|
||||
uint32_t offset, uint32_t length, uint8_t *frubuf)
|
||||
{
|
||||
uint32_t off = offset, tmp, finish;
|
||||
uint32_t off = offset;
|
||||
uint32_t tmp;
|
||||
uint32_t finish;
|
||||
uint32_t size_left_in_buffer;
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
uint8_t msg_data[4];
|
||||
@ -682,10 +679,12 @@ read_fru_area(struct ipmi_intf * intf, struct fru_info *fru, uint8_t id,
|
||||
|
||||
finish = offset + length;
|
||||
if (finish > fru->size) {
|
||||
memset(frubuf + fru->size, 0, length - fru->size);
|
||||
finish = fru->size;
|
||||
lprintf(LOG_NOTICE, "Read FRU Area length %d too large, "
|
||||
"Adjusting to %d",
|
||||
offset + length, finish - offset);
|
||||
length = finish - offset;
|
||||
}
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
@ -721,6 +720,7 @@ read_fru_area(struct ipmi_intf * intf, struct fru_info *fru, uint8_t id,
|
||||
}
|
||||
}
|
||||
|
||||
size_left_in_buffer = length;
|
||||
do {
|
||||
tmp = fru->access ? off >> 1 : off;
|
||||
msg_data[0] = id;
|
||||
@ -762,9 +762,18 @@ read_fru_area(struct ipmi_intf * intf, struct fru_info *fru, uint8_t id,
|
||||
}
|
||||
|
||||
tmp = fru->access ? rsp->data[0] << 1 : rsp->data[0];
|
||||
if(rsp->data_len < 1
|
||||
|| tmp > rsp->data_len - 1
|
||||
|| tmp > size_left_in_buffer)
|
||||
{
|
||||
printf(" Not enough buffer size");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(frubuf, rsp->data + 1, tmp);
|
||||
off += tmp;
|
||||
frubuf += tmp;
|
||||
size_left_in_buffer -= tmp;
|
||||
/* sometimes the size returned in the Info command
|
||||
* is too large. return 0 so higher level function
|
||||
* still attempts to parse what was returned */
|
||||
@ -797,7 +806,9 @@ read_fru_area_section(struct ipmi_intf * intf, struct fru_info *fru, uint8_t id,
|
||||
uint32_t offset, uint32_t length, uint8_t *frubuf)
|
||||
{
|
||||
static uint32_t fru_data_rqst_size = 20;
|
||||
uint32_t off = offset, tmp, finish;
|
||||
uint32_t off = offset;
|
||||
uint32_t tmp, finish;
|
||||
uint32_t size_left_in_buffer;
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
uint8_t msg_data[4];
|
||||
@ -810,10 +821,12 @@ read_fru_area_section(struct ipmi_intf * intf, struct fru_info *fru, uint8_t id,
|
||||
|
||||
finish = offset + length;
|
||||
if (finish > fru->size) {
|
||||
memset(frubuf + fru->size, 0, length - fru->size);
|
||||
finish = fru->size;
|
||||
lprintf(LOG_NOTICE, "Read FRU Area length %d too large, "
|
||||
"Adjusting to %d",
|
||||
offset + length, finish - offset);
|
||||
length = finish - offset;
|
||||
}
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
@ -828,6 +841,8 @@ read_fru_area_section(struct ipmi_intf * intf, struct fru_info *fru, uint8_t id,
|
||||
if (fru->access && fru_data_rqst_size > 16)
|
||||
#endif
|
||||
fru_data_rqst_size = 16;
|
||||
|
||||
size_left_in_buffer = length;
|
||||
do {
|
||||
tmp = fru->access ? off >> 1 : off;
|
||||
msg_data[0] = id;
|
||||
@ -859,8 +874,16 @@ read_fru_area_section(struct ipmi_intf * intf, struct fru_info *fru, uint8_t id,
|
||||
}
|
||||
|
||||
tmp = fru->access ? rsp->data[0] << 1 : rsp->data[0];
|
||||
if(rsp->data_len < 1
|
||||
|| tmp > rsp->data_len - 1
|
||||
|| tmp > size_left_in_buffer)
|
||||
{
|
||||
printf(" Not enough buffer size");
|
||||
return -1;
|
||||
}
|
||||
memcpy((frubuf + off)-offset, rsp->data + 1, tmp);
|
||||
off += tmp;
|
||||
size_left_in_buffer -= tmp;
|
||||
|
||||
/* sometimes the size returned in the Info command
|
||||
* is too large. return 0 so higher level function
|
||||
@ -3019,7 +3042,6 @@ __ipmi_fru_print(struct ipmi_intf * intf, uint8_t id)
|
||||
int
|
||||
ipmi_fru_print(struct ipmi_intf * intf, struct sdr_record_fru_locator * fru)
|
||||
{
|
||||
char desc[17];
|
||||
uint8_t bridged_request = 0;
|
||||
uint32_t save_addr;
|
||||
uint32_t save_channel;
|
||||
@ -3054,10 +3076,10 @@ ipmi_fru_print(struct ipmi_intf * intf, struct sdr_record_fru_locator * fru)
|
||||
fru->device_id == 0)
|
||||
return 0;
|
||||
|
||||
memset(desc, 0, sizeof(desc));
|
||||
memcpy(desc, fru->id_string, fru->id_code & 0x01f);
|
||||
desc[fru->id_code & 0x01f] = 0;
|
||||
printf("FRU Device Description : %s (ID %d)\n", desc, fru->device_id);
|
||||
printf("FRU Device Description : %.*s (ID %d)\n"
|
||||
, SDR_ID_STRLEN(fru)
|
||||
, fru->id_string
|
||||
, fru->device_id);
|
||||
|
||||
switch (fru->dev_type_modifier) {
|
||||
case 0x00:
|
||||
@ -3169,7 +3191,9 @@ ipmi_fru_print_all(struct ipmi_intf * intf)
|
||||
/* set new target address to satellite controller */
|
||||
intf->target_addr = mc->dev_slave_addr;
|
||||
|
||||
printf("FRU Device Description : %-16s\n", mc->id_string);
|
||||
printf("FRU Device Description : %.*s\n"
|
||||
, SDR_ID_STRLEN(fru)
|
||||
, fru->id_string);
|
||||
|
||||
/* print the FRU by issuing FRU commands to the satellite */
|
||||
/* controller. */
|
||||
|
@ -48,10 +48,6 @@
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
/* From src/plugins/ipmi_intf.c: */
|
||||
uint16_t
|
||||
ipmi_intf_get_max_request_data_size(struct ipmi_intf * intf);
|
||||
|
||||
extern int verbose;
|
||||
|
||||
int HpmfwupgUpgrade(struct ipmi_intf *intf, char *imageFilename,
|
||||
|
@ -1260,7 +1260,7 @@ ipmi_lan_set_vlan_id(struct ipmi_intf *intf, uint8_t chan, char *string)
|
||||
rc = 0;
|
||||
goto out;
|
||||
}
|
||||
if (IPMI_LANP_IS_VLAN_VALID(id)) {
|
||||
if (!IPMI_LANP_IS_VLAN_VALID(id)) {
|
||||
lprintf(LOG_ERR,
|
||||
"Retrieved VLAN ID %i is out of "
|
||||
"range <%d..%d>.",
|
||||
@ -1285,7 +1285,7 @@ ipmi_lan_set_vlan_id(struct ipmi_intf *intf, uint8_t chan, char *string)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (IPMI_LANP_IS_VLAN_VALID(id)) {
|
||||
if (!IPMI_LANP_IS_VLAN_VALID(id)) {
|
||||
lprintf(LOG_NOTICE,
|
||||
"VLAN ID must be between %d and %d.",
|
||||
IPMI_LANP_VLAN_ID_MIN,
|
||||
@ -1865,7 +1865,7 @@ ipmi_lan_alert_set(struct ipmi_intf * intf, uint8_t chan, uint8_t alert,
|
||||
if (!p) {
|
||||
return (-1);
|
||||
}
|
||||
memcpy(data, p->data, p->data_len);
|
||||
memcpy(data, p->data, __min(p->data_len, sizeof(data)));
|
||||
/* set new ipaddr */
|
||||
memcpy(data+3, temp, 4);
|
||||
printf("Setting LAN Alert %d IP Address to %d.%d.%d.%d\n", alert,
|
||||
@ -1880,7 +1880,7 @@ ipmi_lan_alert_set(struct ipmi_intf * intf, uint8_t chan, uint8_t alert,
|
||||
if (!p) {
|
||||
return (-1);
|
||||
}
|
||||
memcpy(data, p->data, p->data_len);
|
||||
memcpy(data, p->data, __min(p->data_len, sizeof(data)));
|
||||
/* set new macaddr */
|
||||
memcpy(data+7, temp, 6);
|
||||
printf("Setting LAN Alert %d MAC Address to "
|
||||
@ -1894,7 +1894,7 @@ ipmi_lan_alert_set(struct ipmi_intf * intf, uint8_t chan, uint8_t alert,
|
||||
if (!p) {
|
||||
return (-1);
|
||||
}
|
||||
memcpy(data, p->data, p->data_len);
|
||||
memcpy(data, p->data, __min(p->data_len, sizeof(data)));
|
||||
|
||||
if (strncasecmp(argv[1], "def", 3) == 0 ||
|
||||
strncasecmp(argv[1], "default", 7) == 0) {
|
||||
@ -1920,7 +1920,7 @@ ipmi_lan_alert_set(struct ipmi_intf * intf, uint8_t chan, uint8_t alert,
|
||||
if (!p) {
|
||||
return (-1);
|
||||
}
|
||||
memcpy(data, p->data, p->data_len);
|
||||
memcpy(data, p->data, __min(p->data_len, sizeof(data)));
|
||||
|
||||
if (strncasecmp(argv[1], "on", 2) == 0 ||
|
||||
strncasecmp(argv[1], "yes", 3) == 0) {
|
||||
@ -1945,7 +1945,7 @@ ipmi_lan_alert_set(struct ipmi_intf * intf, uint8_t chan, uint8_t alert,
|
||||
if (!p) {
|
||||
return (-1);
|
||||
}
|
||||
memcpy(data, p->data, p->data_len);
|
||||
memcpy(data, p->data, __min(p->data_len, sizeof(data)));
|
||||
|
||||
if (strncasecmp(argv[1], "pet", 3) == 0) {
|
||||
printf("Setting LAN Alert %d destination to PET Trap\n", alert);
|
||||
@ -1973,7 +1973,7 @@ ipmi_lan_alert_set(struct ipmi_intf * intf, uint8_t chan, uint8_t alert,
|
||||
if (!p) {
|
||||
return (-1);
|
||||
}
|
||||
memcpy(data, p->data, p->data_len);
|
||||
memcpy(data, p->data, __min(p->data_len, sizeof(data)));
|
||||
|
||||
if (str2uchar(argv[1], &data[2]) != 0) {
|
||||
lprintf(LOG_ERR, "Invalid time: %s", argv[1]);
|
||||
@ -1989,7 +1989,7 @@ ipmi_lan_alert_set(struct ipmi_intf * intf, uint8_t chan, uint8_t alert,
|
||||
if (!p) {
|
||||
return (-1);
|
||||
}
|
||||
memcpy(data, p->data, p->data_len);
|
||||
memcpy(data, p->data, __min(p->data_len, sizeof(data)));
|
||||
|
||||
if (str2uchar(argv[1], &data[3]) != 0) {
|
||||
lprintf(LOG_ERR, "Invalid retry: %s", argv[1]);
|
||||
|
@ -844,6 +844,12 @@ ipmi_main(int argc, char ** argv,
|
||||
/* setup log */
|
||||
log_init(progname, 0, verbose);
|
||||
|
||||
/* load the IANA PEN registry */
|
||||
if (ipmi_oem_info_init()) {
|
||||
lprintf(LOG_ERR, "Failed to initialize the OEM info dictionary");
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
/* run OEM setup if found */
|
||||
if (oemtype &&
|
||||
ipmi_oem_setup(ipmi_main_intf, oemtype) < 0) {
|
||||
@ -1063,6 +1069,8 @@ ipmi_main(int argc, char ** argv,
|
||||
devfile = NULL;
|
||||
}
|
||||
|
||||
ipmi_oem_info_free();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
112
lib/ipmi_sdr.c
112
lib/ipmi_sdr.c
@ -219,10 +219,6 @@ static const char *sensor_type_desc[] = {
|
||||
|
||||
void printf_sdr_usage();
|
||||
|
||||
/* From src/plugins/ipmi_intf.c: */
|
||||
uint16_t
|
||||
ipmi_intf_get_max_response_data_size(struct ipmi_intf * intf);
|
||||
|
||||
/** ipmi_sdr_get_unit_string - return units for base/modifier
|
||||
*
|
||||
* @param[in] pct Indicates that units are a percentage
|
||||
@ -1578,22 +1574,14 @@ ipmi_sdr_read_sensor_value(struct ipmi_intf *intf,
|
||||
|
||||
/* Initialize to reading valid value of zero */
|
||||
memset(&sr, 0, sizeof(sr));
|
||||
sr.raw = sensor;
|
||||
|
||||
switch (sdr_record_type) {
|
||||
unsigned int idlen;
|
||||
case (SDR_RECORD_TYPE_FULL_SENSOR):
|
||||
sr.full = (struct sdr_record_full_sensor *)sensor;
|
||||
idlen = sr.full->id_code & 0x1f;
|
||||
idlen = idlen < sizeof(sr.s_id) ?
|
||||
idlen : sizeof(sr.s_id) - 1;
|
||||
memcpy(sr.s_id, sr.full->id_string, idlen);
|
||||
case SDR_RECORD_TYPE_FULL_SENSOR:
|
||||
SDR_ID_TO_CSTRING(sr.s_id, sr.full);
|
||||
break;
|
||||
case SDR_RECORD_TYPE_COMPACT_SENSOR:
|
||||
sr.compact = (struct sdr_record_compact_sensor *)sensor;
|
||||
idlen = sr.compact->id_code & 0x1f;
|
||||
idlen = idlen < sizeof(sr.s_id) ?
|
||||
idlen : sizeof(sr.s_id) - 1;
|
||||
memcpy(sr.s_id, sr.compact->id_string, idlen);
|
||||
SDR_ID_TO_CSTRING(sr.s_id, sr.compact);
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
@ -2252,13 +2240,12 @@ int
|
||||
ipmi_sdr_print_sensor_eventonly(struct ipmi_intf *intf,
|
||||
struct sdr_record_eventonly_sensor *sensor)
|
||||
{
|
||||
char desc[17];
|
||||
char desc[SDR_ID_STRING_MAX + 1];
|
||||
|
||||
if (!sensor)
|
||||
return -1;
|
||||
|
||||
memset(desc, 0, sizeof (desc));
|
||||
snprintf(desc, (sensor->id_code & 0x1f) + 1, "%s", sensor->id_string);
|
||||
SDR_ID_TO_CSTRING(desc, sensor);
|
||||
|
||||
if (verbose) {
|
||||
printf("Sensor ID : %s (0x%x)\n",
|
||||
@ -2301,13 +2288,12 @@ ipmi_sdr_print_sensor_eventonly(struct ipmi_intf *intf,
|
||||
int
|
||||
ipmi_sdr_print_sensor_mc_locator(struct sdr_record_mc_locator *mc)
|
||||
{
|
||||
char desc[17];
|
||||
char desc[SDR_ID_STRING_MAX + 1];
|
||||
|
||||
if (!mc)
|
||||
return -1;
|
||||
|
||||
memset(desc, 0, sizeof (desc));
|
||||
snprintf(desc, (mc->id_code & 0x1f) + 1, "%s", mc->id_string);
|
||||
SDR_ID_TO_CSTRING(desc, mc);
|
||||
|
||||
if (verbose == 0) {
|
||||
if (csv_output)
|
||||
@ -2395,10 +2381,12 @@ ipmi_sdr_print_sensor_mc_locator(struct sdr_record_mc_locator *mc)
|
||||
int
|
||||
ipmi_sdr_print_sensor_generic_locator(struct sdr_record_generic_locator *dev)
|
||||
{
|
||||
char desc[17];
|
||||
char desc[SDR_ID_STRING_MAX + 1];
|
||||
|
||||
memset(desc, 0, sizeof (desc));
|
||||
snprintf(desc, (dev->id_code & 0x1f) + 1, "%s", dev->id_string);
|
||||
if (!dev)
|
||||
return -1;
|
||||
|
||||
SDR_ID_TO_CSTRING(desc, dev);
|
||||
|
||||
if (!verbose) {
|
||||
if (csv_output)
|
||||
@ -2450,10 +2438,12 @@ ipmi_sdr_print_sensor_generic_locator(struct sdr_record_generic_locator *dev)
|
||||
int
|
||||
ipmi_sdr_print_sensor_fru_locator(struct sdr_record_fru_locator *fru)
|
||||
{
|
||||
char desc[17];
|
||||
char desc[SDR_ID_STRING_MAX + 1];
|
||||
|
||||
memset(desc, 0, sizeof (desc));
|
||||
snprintf(desc, (fru->id_code & 0x1f) + 1, "%s", fru->id_string);
|
||||
if (!fru)
|
||||
return -1;
|
||||
|
||||
SDR_ID_TO_CSTRING(desc, fru);
|
||||
|
||||
if (!verbose) {
|
||||
if (csv_output)
|
||||
@ -2613,17 +2603,20 @@ ipmi_sdr_print_sensor_oem(struct sdr_record_oem *oem)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* ipmi_sdr_print_name_from_rawentry - Print SDR name from raw data
|
||||
/**
|
||||
* Get SDR record name from raw data
|
||||
*
|
||||
* @type: sensor type
|
||||
* @raw: raw sensor data
|
||||
* @param[in] type SDR record type
|
||||
* @param[in] raw raw SDR record data
|
||||
* @param[out] buf The SDR record description target buffer
|
||||
* @param[in] len The length of the target buffer
|
||||
*
|
||||
* returns 0 on success
|
||||
* returns -1 on error
|
||||
* @returns Error status
|
||||
* @retval 0 Success
|
||||
* @retval -1 Error
|
||||
*/
|
||||
int
|
||||
ipmi_sdr_print_name_from_rawentry(uint16_t id,
|
||||
uint8_t type, uint8_t *raw)
|
||||
sdr_get_name_from_rawentry(uint8_t type, void *raw, char *buf, size_t len)
|
||||
{
|
||||
union {
|
||||
struct sdr_record_full_sensor *full;
|
||||
@ -2634,39 +2627,50 @@ ipmi_sdr_print_name_from_rawentry(uint16_t id,
|
||||
struct sdr_record_mc_locator *mcloc;
|
||||
struct sdr_record_entity_assoc *entassoc;
|
||||
struct sdr_record_oem *oem;
|
||||
void *raw;
|
||||
} record;
|
||||
|
||||
int rc =0;
|
||||
char desc[17];
|
||||
memset(desc, ' ', sizeof (desc));
|
||||
char desc[SDR_ID_STRING_MAX + 1] = { 0 };
|
||||
record.raw = raw;
|
||||
|
||||
switch ( type) {
|
||||
/* Sensor records */
|
||||
|
||||
case SDR_RECORD_TYPE_FULL_SENSOR:
|
||||
record.full = (struct sdr_record_full_sensor *) raw;
|
||||
snprintf(desc, (record.full->id_code & 0x1f) +1, "%s",
|
||||
(const char *)record.full->id_string);
|
||||
SDR_ID_TO_CSTRING(desc, record.full);
|
||||
break;
|
||||
|
||||
case SDR_RECORD_TYPE_COMPACT_SENSOR:
|
||||
record.compact = (struct sdr_record_compact_sensor *) raw ;
|
||||
snprintf(desc, (record.compact->id_code & 0x1f) +1, "%s",
|
||||
(const char *)record.compact->id_string);
|
||||
SDR_ID_TO_CSTRING(desc, record.compact);
|
||||
break;
|
||||
|
||||
case SDR_RECORD_TYPE_EVENTONLY_SENSOR:
|
||||
record.eventonly = (struct sdr_record_eventonly_sensor *) raw ;
|
||||
snprintf(desc, (record.eventonly->id_code & 0x1f) +1, "%s",
|
||||
(const char *)record.eventonly->id_string);
|
||||
break;
|
||||
case SDR_RECORD_TYPE_MC_DEVICE_LOCATOR:
|
||||
record.mcloc = (struct sdr_record_mc_locator *) raw ;
|
||||
snprintf(desc, (record.mcloc->id_code & 0x1f) +1, "%s",
|
||||
(const char *)record.mcloc->id_string);
|
||||
SDR_ID_TO_CSTRING(desc, record.eventonly);
|
||||
break;
|
||||
|
||||
/* Device locator records */
|
||||
|
||||
case SDR_RECORD_TYPE_GENERIC_DEVICE_LOCATOR:
|
||||
SDR_ID_TO_CSTRING(desc, record.genloc);
|
||||
break;
|
||||
|
||||
case SDR_RECORD_TYPE_FRU_DEVICE_LOCATOR:
|
||||
SDR_ID_TO_CSTRING(desc, record.fruloc);
|
||||
break;
|
||||
|
||||
case SDR_RECORD_TYPE_MC_DEVICE_LOCATOR:
|
||||
SDR_ID_TO_CSTRING(desc, record.mcloc);
|
||||
break;
|
||||
|
||||
/* All other records don't have the id_string field */
|
||||
|
||||
default:
|
||||
rc = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(buf, desc, __min(sizeof(buf), len));
|
||||
|
||||
lprintf(LOG_INFO, "ID: 0x%04x , NAME: %-16s", id, desc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -250,6 +250,7 @@ sdrr_get_records(struct ipmi_intf *intf, struct ipmi_sdr_iterator *itr,
|
||||
|
||||
while ((header = ipmi_sdr_get_next_header(intf, itr))) {
|
||||
struct sdr_record_list *sdrr;
|
||||
char desc[SDR_ID_STRING_MAX + 1];
|
||||
|
||||
sdrr = malloc(sizeof (struct sdr_record_list));
|
||||
if (!sdrr) {
|
||||
@ -263,7 +264,8 @@ sdrr_get_records(struct ipmi_intf *intf, struct ipmi_sdr_iterator *itr,
|
||||
sdrr->type = header->type;
|
||||
sdrr->length = header->length;
|
||||
sdrr->raw = ipmi_sdr_get_record(intf, header, itr);
|
||||
(void)ipmi_sdr_print_name_from_rawentry(sdrr->id, sdrr->type,sdrr->raw);
|
||||
(void)sdr_get_name_from_rawentry(sdrr->type, sdrr->raw, desc, sizeof(desc));
|
||||
lprintf(LOG_INFO, "ID: 0x%04x , NAME: %s", sdrr->id, desc);
|
||||
|
||||
/* put in the record queue */
|
||||
if (!queue->head)
|
||||
|
@ -454,10 +454,10 @@ get_kontron_evt_desc(struct ipmi_intf *__UNUSED__(intf), struct sel_event_record
|
||||
}
|
||||
|
||||
char *
|
||||
get_newisys_evt_desc(struct ipmi_intf * intf, struct sel_event_record * rec)
|
||||
get_viking_evt_desc(struct ipmi_intf * intf, struct sel_event_record * rec)
|
||||
{
|
||||
/*
|
||||
* Newisys OEM event descriptions can be retrieved through an
|
||||
* Viking OEM event descriptions can be retrieved through an
|
||||
* OEM IPMI command.
|
||||
*/
|
||||
struct ipmi_rs * rsp;
|
||||
@ -495,17 +495,17 @@ get_newisys_evt_desc(struct ipmi_intf * intf, struct sel_event_record * rec)
|
||||
/* Verify our response before we use it */
|
||||
if (rsp->data_len < 5)
|
||||
{
|
||||
lprintf(LOG_ERR, "Newisys OEM response too short");
|
||||
lprintf(LOG_ERR, "Viking OEM response too short");
|
||||
return NULL;
|
||||
}
|
||||
else if (rsp->data_len != (4 + rsp->data[3]))
|
||||
{
|
||||
lprintf(LOG_ERR, "Newisys OEM response has unexpected length");
|
||||
lprintf(LOG_ERR, "Viking OEM response has unexpected length");
|
||||
return NULL;
|
||||
}
|
||||
else if (IPM_DEV_MANUFACTURER_ID(rsp->data) != IPMI_OEM_NEWISYS)
|
||||
else if (IPM_DEV_MANUFACTURER_ID(rsp->data) != IPMI_OEM_VIKING)
|
||||
{
|
||||
lprintf(LOG_ERR, "Newisys OEM response has unexpected length");
|
||||
lprintf(LOG_ERR, "Viking OEM response has unexpected length");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -1205,8 +1205,8 @@ ipmi_get_oem_desc(struct ipmi_intf * intf, struct sel_event_record * rec)
|
||||
|
||||
switch (ipmi_get_oem(intf))
|
||||
{
|
||||
case IPMI_OEM_NEWISYS:
|
||||
desc = get_newisys_evt_desc(intf, rec);
|
||||
case IPMI_OEM_VIKING:
|
||||
desc = get_viking_evt_desc(intf, rec);
|
||||
break;
|
||||
case IPMI_OEM_KONTRON:
|
||||
desc = get_kontron_evt_desc(intf, rec);
|
||||
@ -2743,6 +2743,7 @@ ipmi_sel_set_time(struct ipmi_intf * intf, const char * time_string)
|
||||
struct ipmi_rs *rsp;
|
||||
struct ipmi_rq req;
|
||||
struct tm tm = {0};
|
||||
uint8_t msg_data[4] = {0};
|
||||
time_t t;
|
||||
const char *time_format = "%x %X"; /* Use locale-defined format */
|
||||
|
||||
@ -2787,8 +2788,9 @@ ipmi_sel_set_time(struct ipmi_intf * intf, const char * time_string)
|
||||
* At this point `t` is UTC. Convert it to LE and send.
|
||||
*/
|
||||
|
||||
req.msg.data = msg_data;
|
||||
htoipmi32(t, req.msg.data);
|
||||
req.msg.data_len = 4;
|
||||
req.msg.data_len = sizeof(msg_data);
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (!rsp || rsp->ccode) {
|
||||
|
@ -309,8 +309,10 @@ ipmi_get_session_info(struct ipmi_intf * intf,
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(&session_info, rsp->data, rsp->data_len);
|
||||
print_session_info(&session_info, rsp->data_len);
|
||||
memcpy(&session_info, rsp->data,
|
||||
__min(rsp->data_len, sizeof(session_info)));
|
||||
print_session_info(&session_info,
|
||||
__min(rsp->data_len, sizeof(session_info)));
|
||||
}
|
||||
break;
|
||||
|
||||
@ -341,8 +343,10 @@ ipmi_get_session_info(struct ipmi_intf * intf,
|
||||
break;
|
||||
}
|
||||
|
||||
memcpy(&session_info, rsp->data, rsp->data_len);
|
||||
print_session_info(&session_info, rsp->data_len);
|
||||
memcpy(&session_info, rsp->data,
|
||||
__min(rsp->data_len, sizeof(session_info)));
|
||||
print_session_info(&session_info,
|
||||
__min(rsp->data_len, sizeof(session_info)));
|
||||
|
||||
} while (i <= session_info.session_slot_count);
|
||||
break;
|
||||
|
1030
lib/ipmi_strings.c
1030
lib/ipmi_strings.c
File diff suppressed because it is too large
Load Diff
@ -434,7 +434,7 @@ print_user_usage(void)
|
||||
lprintf(LOG_NOTICE,
|
||||
" set name <user id> <username>");
|
||||
lprintf(LOG_NOTICE,
|
||||
" set password <user id> [<password> <16|20>]");
|
||||
" set password <user id> [<password> [<16|20>]]");
|
||||
lprintf(LOG_NOTICE,
|
||||
" disable <user id>");
|
||||
lprintf(LOG_NOTICE,
|
||||
@ -626,12 +626,17 @@ ipmi_user_mod(struct ipmi_intf *intf, int argc, char **argv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define USER_PW_IPMI15_LEN 16 /* IPMI 1.5 only allowed for 16 bytes */
|
||||
#define USER_PW_IPMI20_LEN 20 /* IPMI 2.0 allows for 20 bytes */
|
||||
#define USER_PW_MAX_LEN USER_PW_IPMI20_LEN
|
||||
|
||||
int
|
||||
ipmi_user_password(struct ipmi_intf *intf, int argc, char **argv)
|
||||
{
|
||||
char *password = NULL;
|
||||
int ccode = 0;
|
||||
uint8_t password_type = 16;
|
||||
uint8_t password_type = USER_PW_IPMI15_LEN;
|
||||
size_t password_len;
|
||||
uint8_t user_id = 0;
|
||||
if (is_ipmi_user_id(argv[2], &user_id)) {
|
||||
return (-1);
|
||||
@ -640,52 +645,63 @@ ipmi_user_password(struct ipmi_intf *intf, int argc, char **argv)
|
||||
if (argc == 3) {
|
||||
/* We need to prompt for a password */
|
||||
char *tmp;
|
||||
size_t tmplen;
|
||||
password = ask_password(user_id);
|
||||
if (!password) {
|
||||
lprintf(LOG_ERR, "ipmitool: malloc failure");
|
||||
return (-1);
|
||||
}
|
||||
tmp = ask_password(user_id);
|
||||
tmplen = strnlen(tmp, USER_PW_MAX_LEN + 1);
|
||||
if (!tmp) {
|
||||
lprintf(LOG_ERR, "ipmitool: malloc failure");
|
||||
return (-1);
|
||||
}
|
||||
if (strlen(password) != strlen(tmp)
|
||||
|| strncmp(password, tmp, strlen(tmp))) {
|
||||
lprintf(LOG_ERR, "Passwords do not match.");
|
||||
if (strncmp(password, tmp, tmplen)) {
|
||||
lprintf(LOG_ERR, "Passwords do not match or are "
|
||||
"longer than %d", USER_PW_MAX_LEN);
|
||||
return (-1);
|
||||
}
|
||||
} else {
|
||||
password = argv[3];
|
||||
if (argc > 4) {
|
||||
if ((str2uchar(argv[4], &password_type) != 0)
|
||||
|| (password_type != 16 && password_type != 20)) {
|
||||
lprintf(LOG_ERR, "Invalid password length '%s'", argv[4]);
|
||||
return (-1);
|
||||
}
|
||||
} else {
|
||||
password_type = 16;
|
||||
}
|
||||
}
|
||||
|
||||
if (!password) {
|
||||
lprintf(LOG_ERR, "Unable to parse password argument.");
|
||||
return (-1);
|
||||
} else if (strlen(password) > 20) {
|
||||
lprintf(LOG_ERR, "Password is too long (> 20 bytes)");
|
||||
}
|
||||
|
||||
password_len = strnlen(password, USER_PW_MAX_LEN + 1);
|
||||
|
||||
if (argc > 4) {
|
||||
if ((str2uchar(argv[4], &password_type) != 0)
|
||||
|| (password_type != USER_PW_IPMI15_LEN
|
||||
&& password_type != USER_PW_IPMI20_LEN))
|
||||
{
|
||||
lprintf(LOG_ERR, "Invalid password length '%s'",
|
||||
argv[4]);
|
||||
return (-1);
|
||||
}
|
||||
} else if (password_len > USER_PW_IPMI15_LEN) {
|
||||
password_type = USER_PW_IPMI20_LEN;
|
||||
}
|
||||
|
||||
if (password_len > password_type) {
|
||||
lprintf(LOG_ERR, "Password is too long (> %d bytes)",
|
||||
password_type);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
ccode = _ipmi_set_user_password(intf, user_id,
|
||||
IPMI_PASSWORD_SET_PASSWORD, password,
|
||||
password_type > 16);
|
||||
IPMI_PASSWORD_SET_PASSWORD, password,
|
||||
password_type > USER_PW_IPMI15_LEN);
|
||||
if (eval_ccode(ccode) != 0) {
|
||||
lprintf(LOG_ERR, "Set User Password command failed (user %d)",
|
||||
user_id);
|
||||
user_id);
|
||||
return (-1);
|
||||
} else {
|
||||
printf("Set User Password command successful (user %d)\n",
|
||||
user_id);
|
||||
user_id);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,7 @@
|
||||
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/include
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/include
|
||||
|
||||
EXTRA_LTLIBRARIES = libintf_dbus.la
|
||||
noinst_LTLIBRARIES = @INTF_DBUS_LIB@
|
||||
|
@ -761,12 +761,6 @@ ipmi_lan_poll_single(struct ipmi_intf * intf)
|
||||
if (payload_size > 8) {
|
||||
printbuf(&rsp->data[offset], (rsp->data_len-offset-1),
|
||||
"bridge command response");
|
||||
/*
|
||||
* decrement payload size
|
||||
* (cks2 for outer Send Message)
|
||||
*/
|
||||
payload_size--;
|
||||
|
||||
/*
|
||||
* need to make a loop for embedded bridged response
|
||||
*/
|
||||
@ -793,6 +787,9 @@ ipmi_lan_poll_single(struct ipmi_intf * intf)
|
||||
if (extra_data_length > 0) {
|
||||
rsp->data_len = extra_data_length;
|
||||
memmove(rsp->data, rsp->data + offset, extra_data_length);
|
||||
offset = 0;
|
||||
payload_start = 0;
|
||||
payload_size = extra_data_length;
|
||||
} else {
|
||||
rsp->data_len = 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user