mirror of
https://github.com/ipmitool/ipmitool.git
synced 2025-07-01 10:13:35 +00:00
Compare commits
51 Commits
IPMITOOL_1
...
IPMITOOL_1
Author | SHA1 | Date | |
---|---|---|---|
aa8a63d0d4 | |||
ae3c316bbb | |||
77268f7daa | |||
a6793b9430 | |||
e8170fd6b6 | |||
0b3db22dab | |||
c7bc504b87 | |||
50b4815cf0 | |||
4677f14f6c | |||
6e6d775ac8 | |||
44cbf081a6 | |||
42c1c9123c | |||
3bf0d0c68e | |||
99fc2e8a83 | |||
d7af26b64b | |||
630be3c669 | |||
6f2eeed320 | |||
15b8801d0b | |||
d47cd125fe | |||
6bc047da44 | |||
224844746a | |||
222180ca52 | |||
970a87eb1a | |||
68556c2a43 | |||
c634d2a080 | |||
95044acb5d | |||
c199b86143 | |||
e09dc5950c | |||
85d138da01 | |||
69eeda859e | |||
05344c9a45 | |||
2a5ea8b9ee | |||
a502ab31d1 | |||
ccf104d610 | |||
572f2df8bb | |||
9c87f801a4 | |||
59b1d83751 | |||
ef055c6246 | |||
0710a0a98e | |||
706bb54764 | |||
d234596ac5 | |||
4bfdf06132 | |||
6e5cdb2c20 | |||
eb116adf53 | |||
8f48a7021a | |||
41a64a0f93 | |||
1e1058db49 | |||
569b8bf5d7 | |||
ceae2f37bf | |||
1070546b2a | |||
e0f8bb52bb |
@ -1,3 +1,16 @@
|
||||
version 1.5.9
|
||||
* Add ability to get a particular sensor by name
|
||||
* Add ability to set a particular sensor threshold
|
||||
* Add support for displaying V2 channel authentication levels
|
||||
* Add README for rrdtool scripts in contrib directory
|
||||
* Improve lan interface retry handling
|
||||
* Support prompting for password or reading from environment
|
||||
* Move chaninfo command into channel subcommand
|
||||
* Fix reservation ID handling when two sessions open to BMC
|
||||
* Fix reading of large FRU data
|
||||
* Add configure option for changing binary to ipmiadm for Solaris
|
||||
* Fix compile problem on Solaris 8
|
||||
|
||||
version 1.5.8
|
||||
* Enable static compilation of interfaces
|
||||
* Fix types to be 64-bit safe
|
||||
|
@ -32,7 +32,9 @@
|
||||
# in the design, construction, operation or maintenance of any nuclear
|
||||
# facility.
|
||||
|
||||
EXTRA_DIST = ipmitool.spec.in AUTHORS COPYING ChangeLog debian/*
|
||||
EXTRA_DIST = ipmitool.spec.in AUTHORS COPYING ChangeLog \
|
||||
debian/changelog debian/control debian/copyright \
|
||||
debian/dirs debian/docs debian/rules
|
||||
|
||||
MAINTAINERCLEANFILES = Makefile.in aclocal.m4 configure configure-stamp \
|
||||
config.guess config.sub depcomp install-sh ltmain.sh missing \
|
||||
|
@ -50,6 +50,7 @@ AC_FUNC_STAT
|
||||
AC_FUNC_STRTOD
|
||||
AC_CHECK_FUNCS([alarm gethostbyname socket select])
|
||||
AC_CHECK_FUNCS([memmove memset strchr strdup strerror])
|
||||
AC_CHECK_FUNCS([getpassphrase])
|
||||
|
||||
dnl check for byteswap functionality
|
||||
AC_CHECK_HEADERS([sys/byteorder.h byteswap.h])
|
||||
@ -75,15 +76,29 @@ if test "x$exec_prefix" = "xNONE"; then
|
||||
exec_prefix="$prefix"
|
||||
fi
|
||||
|
||||
|
||||
dnl Solaris convention is command-line tools have *adm and GUIs have *tool suffix
|
||||
IPMITOOL_BIN="ipmitool"
|
||||
AC_ARG_ENABLE([ipmiadm],
|
||||
[[ --enable-ipmiadm enable rename of ipmitool to ipmiadm [default=no]]],,enable_ipmiadm=no)
|
||||
AM_CONDITIONAL(IPMIADM, test "x$enable_ipmiadm" = "xyes")
|
||||
if test "x$enable_ipmiadm" = "xyes"; then
|
||||
IPMITOOL_BIN="ipmiadm"
|
||||
fi
|
||||
AC_DEFINE_UNQUOTED(IPMITOOL_BIN, "$IPMITOOL_BIN", "IPMItool binary name")
|
||||
AC_SUBST(IPMITOOL_BIN)
|
||||
|
||||
|
||||
dnl enable plugins for interfaces
|
||||
AC_ARG_WITH([plugin-path],
|
||||
[[ --with-plugin-path=DIR Set plugin path to DIR]],
|
||||
[pluginpath="$withval"],
|
||||
[pluginpath="${exec_prefix}/lib/ipmitool"])
|
||||
[pluginpath="${exec_prefix}/lib/${IPMITOOL_BIN}"])
|
||||
|
||||
AC_DEFINE_UNQUOTED(PLUGIN_PATH, "$pluginpath", "IPMI interface plugin path")
|
||||
AC_SUBST(pluginpath)
|
||||
|
||||
|
||||
STATIC_INTF_LIST=
|
||||
STATIC_INTF=
|
||||
STATIC_INTF_EXT=
|
||||
@ -147,13 +162,22 @@ AC_SUBST(STATIC_INTF)
|
||||
AC_SUBST(STATIC_INTF_EXT)
|
||||
AC_SUBST(STATIC_INTF_LIB)
|
||||
|
||||
dnl Enable ipmi event daemon binary that requires OpenIPMI
|
||||
AC_ARG_ENABLE([ipmievd],
|
||||
[[ --enable-ipmievd enable IPMI event daemon [default=no]]],,enable_ipmievd=no)
|
||||
AM_CONDITIONAL(IPMIEVD, test "x$enable_ipmievd" = "xyes")
|
||||
if test "x$enable_ipmievd" = "xyes"; then
|
||||
IPMIEVD_SRC="ipmievd.c"
|
||||
IPMIEVD_BIN="ipmievd"
|
||||
fi
|
||||
AC_SUBST(IPMIEVD_SRC)
|
||||
AC_SUBST(IPMIEVD_BIN)
|
||||
|
||||
|
||||
AC_CONFIG_FILES([ipmitool.spec
|
||||
Makefile
|
||||
doc/Makefile
|
||||
doc/ipmitool.1
|
||||
contrib/Makefile
|
||||
lib/Makefile
|
||||
include/Makefile
|
||||
@ -169,6 +193,7 @@ AC_OUTPUT
|
||||
AC_MSG_RESULT([])
|
||||
AC_MSG_RESULT([$PACKAGE $VERSION])
|
||||
AC_MSG_RESULT([])
|
||||
AC_MSG_RESULT([ IPMItool Binary....... : $IPMITOOL_BIN])
|
||||
AC_MSG_RESULT([ Interface Path........ : $pluginpath])
|
||||
AC_MSG_RESULT([ Static Interfaces..... : $STATIC_INTF_LIST])
|
||||
AC_MSG_RESULT([ Dynamic Interfaces.... : $DYNAMIC_INTF_LIST])
|
||||
|
@ -34,5 +34,5 @@
|
||||
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
||||
EXTRA_DIST = collect_data.sh create_rrds.sh create_webpage.sh
|
||||
EXTRA_DIST = collect_data.sh create_rrds.sh create_webpage_compact.sh create_webpage.sh
|
||||
|
||||
|
95
ipmitool/contrib/README
Normal file
95
ipmitool/contrib/README
Normal file
@ -0,0 +1,95 @@
|
||||
|
||||
Graphs for ipmitool
|
||||
-------------------
|
||||
|
||||
This is a set of shell-scripts to quickly create a webpage with pretty graphs!
|
||||
|
||||
Prerequisites are a webserver with cgi-bin support and RRDtool, a data
|
||||
collection and graphing utility you can get here:
|
||||
|
||||
http://people.ee.ethz.ch/~oetiker/webtools/rrdtool/
|
||||
|
||||
|
||||
First, decide on a directory where to store the RRDtool database files and make
|
||||
sure it exists. The user that will run the cronjob to collect updates must have
|
||||
write permissions in this dir.
|
||||
|
||||
Next, you'll need to edit some variables at the top of each script.
|
||||
|
||||
Common to all scripts:
|
||||
|
||||
hostname Override this if you are collecting data from a remote host,
|
||||
or if the $HOSTNAME variable is incorrect.
|
||||
|
||||
ipmi_cmd Command line used to call ipmitool. Default is to collect
|
||||
data from the local server using OpenIPMI.
|
||||
|
||||
If you want to collect data from a remote host, add the
|
||||
-I lan, -H, -U and -P options as necessary.
|
||||
|
||||
BIG NOTE! I do not recommend using remote data collection since
|
||||
you'll have to store the password in the script. If you do,
|
||||
make sure unauthorized people can't read or execute the scripts
|
||||
or they'll be able to wreak havoc on your server.
|
||||
|
||||
rrd_dir Enter the dir where to store the RRDtool database here.
|
||||
|
||||
|
||||
Now you can get the data collection going. Run create_rrds.sh to create the
|
||||
RDDtool database, you'll find one .rrd file per sensor in the designated dir.
|
||||
Add a line to your crontab that executes collect_data.sh every 5 minutes.
|
||||
|
||||
Something like this:
|
||||
*/5 * * * * /usr/local/bin/collect_data.sh
|
||||
|
||||
If you are a Solaris user you'll have to write the more verbose:
|
||||
0,5,10,15,20,25,30,35,40,45,50,55 * * * * /usr/local/bin/collect_data.sh
|
||||
|
||||
|
||||
Finally it's time to create the webpage, begin with editing some more variables
|
||||
in the create_webpage.sh and/or create_webpage_compact.sh scripts:
|
||||
|
||||
rrdcgi Full path to the rrdcgi executable.
|
||||
|
||||
img_dir Directory to store the graph images. This path must be within
|
||||
the document root and writable by the web server user.
|
||||
|
||||
Example: /usr/local/apache2/htdocs/images/graphs
|
||||
|
||||
web_dir Relative path of the URL where the images will show up
|
||||
on the web server.
|
||||
|
||||
Example: With the img_dir path above the corresponding web_dir
|
||||
would be /images/graphs
|
||||
|
||||
graph_width Size of the graph area in pixels (excluding title, legends etc.)
|
||||
graph_height
|
||||
|
||||
graph_daily Decide which of daily, weekly and monthly graphs you want
|
||||
graph_weekly included on the page.
|
||||
graph_monthly
|
||||
|
||||
|
||||
Finally run the create webpage script and store the output as a cgi-script and
|
||||
don't forget to make it executable.
|
||||
|
||||
Example:
|
||||
|
||||
create_webpage.sh > /usr/local/apache2/cgi-bin/my_ipmi_graphs.cgi
|
||||
chmod 755 /usr/local/apache2/cgi-bin/my_ipmi_graphs.cgi
|
||||
|
||||
Now you can surf to http://my.server.com/cgi-bin/my_ipmi_graphs.cgi and enjoy!
|
||||
|
||||
|
||||
The difference between create_webpage.sh and create_webpage_compact.sh is that
|
||||
the first script displays sensor thresholds in the graphs. The second script
|
||||
collects all sensors that measure the same unit into the same graph thus
|
||||
producing a lot fewer graphs.
|
||||
|
||||
Note, RRDtool sometimes scales the graphs such that the sensor thresholds
|
||||
fall outside the visible area.
|
||||
|
||||
|
||||
Happy graphing!
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2003 Fredrik Ohrn. All Rights Reserved.
|
||||
# Copyright (c) 2003-2004 Fredrik Ohrn. All Rights Reserved.
|
||||
#
|
||||
# See the included COPYING file for license details.
|
||||
#
|
||||
@ -22,20 +22,30 @@ img_dir=/usr/local/apache2/htdocs/images/graphs
|
||||
# Where will the graphs show up on the webserver?
|
||||
web_dir=/images/graphs
|
||||
|
||||
# Size of graph area (excluding title, legends etc.)
|
||||
graph_width=500
|
||||
graph_height=150
|
||||
|
||||
# Graphs to include on page
|
||||
graph_daily=1
|
||||
graph_weekly=1
|
||||
graph_monthly=0
|
||||
|
||||
|
||||
# No need to edit below this point.
|
||||
|
||||
color[0]="0000FF"
|
||||
color[1]="00FF00"
|
||||
color[2]="FF0000"
|
||||
color[3]="FFFF00"
|
||||
color[4]="FF00FF"
|
||||
color[5]="00FFFF"
|
||||
color[6]="4444AA"
|
||||
color[7]="44AA44"
|
||||
color[8]="AA4444"
|
||||
color[9]="AAAA44"
|
||||
color[10]="AA44AA"
|
||||
color[11]="44AAAA"
|
||||
color[0]="2020FF"
|
||||
color[1]="20FF20"
|
||||
color[2]="FF2020"
|
||||
color[3]="FF21FF"
|
||||
color[4]="21FFFF"
|
||||
color[5]="FFFF21"
|
||||
color[6]="8F21FF"
|
||||
color[7]="21FF8F"
|
||||
color[8]="FF8F21"
|
||||
color[9]="FF2190"
|
||||
color[10]="2190FF"
|
||||
color[11]="90FF21"
|
||||
|
||||
cat << EOF
|
||||
#!$rrdcgi
|
||||
@ -151,38 +161,48 @@ for group in $groups ; do
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "<h3>${!group_title}</h3>"
|
||||
|
||||
cat << EOF
|
||||
<h3>${!group_title}</h3>
|
||||
if [ "$graph_daily" -ne 0 ] ; then
|
||||
cat << EOF
|
||||
<RRD::GRAPH "$img_dir/$hostname-$group-daily.gif"
|
||||
--imginfo "<img src="$web_dir/%s" width="%lu" height="%lu">"
|
||||
--lazy
|
||||
--height 200
|
||||
--vertical-label "${!group_unit}"
|
||||
--title "Daily graph"
|
||||
--width 576 ${!group} $thres
|
||||
--height $graph_height
|
||||
--width $graph_width ${!group} $thres
|
||||
>
|
||||
EOF
|
||||
fi
|
||||
|
||||
if [ "$graph_weekly" -ne 0 ] ; then
|
||||
cat << EOF
|
||||
<RRD::GRAPH "$img_dir/$hostname-$group-weekly.gif"
|
||||
--imginfo "<img src="$web_dir/%s" width="%lu" height="%lu">"
|
||||
--lazy
|
||||
--start -7d
|
||||
--height 200
|
||||
--vertical-label "${!group_unit}"
|
||||
--title "Weelky graph"
|
||||
--width 672 ${!group} $thres
|
||||
--height $graph_height
|
||||
--width $graph_width ${!group} $thres
|
||||
>
|
||||
EOF
|
||||
#<RRD::GRAPH "$img_dir/$hostname-$group-monthly.gif"
|
||||
# --imginfo "<img src="$web_dir/%s" width="%lu" height="%lu">"
|
||||
# --lazy
|
||||
# --start -30d
|
||||
# --height 200
|
||||
# --vertical-label "${!group_unit}"
|
||||
# --title "Monthly graph"
|
||||
# --width 720 ${!group} $thres
|
||||
#>
|
||||
#EOF
|
||||
fi
|
||||
|
||||
if [ "$graph_monthly" -ne 0 ] ; then
|
||||
cat << EOF
|
||||
<RRD::GRAPH "$img_dir/$hostname-$group-monthly.gif"
|
||||
--imginfo "<img src="$web_dir/%s" width="%lu" height="%lu">"
|
||||
--lazy
|
||||
--start -30d
|
||||
--vertical-label "${!group_unit}"
|
||||
--title "Monthly graph"
|
||||
--height $graph_height
|
||||
--width $graph_width ${!group} $thres
|
||||
>
|
||||
EOF
|
||||
fi
|
||||
done
|
||||
|
||||
cat << EOF
|
||||
|
151
ipmitool/contrib/create_webpage_compact.sh
Executable file
151
ipmitool/contrib/create_webpage_compact.sh
Executable file
@ -0,0 +1,151 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2003-2004 Fredrik Ohrn. All Rights Reserved.
|
||||
#
|
||||
# See the included COPYING file for license details.
|
||||
#
|
||||
|
||||
# Edit the variables
|
||||
|
||||
hostname=$HOSTNAME
|
||||
|
||||
ipmi_cmd="/usr/local/bin/ipmitool -I open"
|
||||
rrd_dir="/some/dir/rrd"
|
||||
|
||||
# Full path to the rrdcgi executable.
|
||||
rrdcgi=/usr/local/bin/rrdcgi
|
||||
|
||||
# Where should rrdcgi store the graphs? This path must be within the
|
||||
# document root and writable by the webserver user.
|
||||
img_dir=/usr/local/apache2/htdocs/images/graphs
|
||||
|
||||
# Where will the graphs show up on the webserver?
|
||||
web_dir=/images/graphs
|
||||
|
||||
# Size of graph area (excluding title, legends etc.)
|
||||
graph_width=500
|
||||
graph_height=150
|
||||
|
||||
# Graphs to include on page
|
||||
graph_daily=1
|
||||
graph_weekly=1
|
||||
graph_monthly=0
|
||||
|
||||
|
||||
# No need to edit below this point.
|
||||
|
||||
color[0]="2020FF"
|
||||
color[1]="20FF20"
|
||||
color[2]="FF2020"
|
||||
color[3]="FF21FF"
|
||||
color[4]="21FFFF"
|
||||
color[5]="FFFF21"
|
||||
color[6]="8F21FF"
|
||||
color[7]="21FF8F"
|
||||
color[8]="FF8F21"
|
||||
color[9]="FF2190"
|
||||
color[10]="2190FF"
|
||||
color[11]="90FF21"
|
||||
|
||||
cat << EOF
|
||||
#!$rrdcgi
|
||||
<html>
|
||||
<head>
|
||||
<title>$hostname</title>
|
||||
<RRD::GOODFOR 300>
|
||||
<body>
|
||||
<h2>$hostname</h2>
|
||||
EOF
|
||||
|
||||
|
||||
IFS="
|
||||
"
|
||||
|
||||
i=0
|
||||
groups=
|
||||
|
||||
for line in `eval $ipmi_cmd -c -v sdr list full` ; do
|
||||
|
||||
IFS=,
|
||||
|
||||
split=($line)
|
||||
|
||||
file="$rrd_dir/$hostname-${split[0]}.rrd"
|
||||
group=`echo "${split[2]}" | tr ' .-' ___`
|
||||
|
||||
group_color=${group}_color
|
||||
|
||||
if [ -z "${!group}" ] ; then
|
||||
groups="$groups $group"
|
||||
|
||||
declare $group_color=0
|
||||
|
||||
group_unit=${group}_unit
|
||||
declare $group_unit="${split[2]}"
|
||||
fi
|
||||
|
||||
declare $group="${!group}
|
||||
DEF:var$i=\"$file\":var:AVERAGE LINE1:var$i#${color[${!group_color}]}:\"${split[0]}\""
|
||||
|
||||
declare $group_color=$[ ${!group_color} + 1 ]
|
||||
|
||||
c=$[ c + 1 ]
|
||||
i=$[ i + 1 ]
|
||||
done
|
||||
|
||||
IFS=" "
|
||||
|
||||
for group in $groups ; do
|
||||
|
||||
group_unit=${group}_unit
|
||||
|
||||
IFS=,
|
||||
|
||||
echo "<h3>${!group_unit}</h3>"
|
||||
|
||||
if [ "$graph_daily" -ne 0 ] ; then
|
||||
cat << EOF
|
||||
<RRD::GRAPH "$img_dir/$hostname-$group-daily.gif"
|
||||
--imginfo "<img src="$web_dir/%s" width="%lu" height="%lu">"
|
||||
--lazy
|
||||
--vertical-label "${!group_unit}"
|
||||
--title "Daily graph"
|
||||
--height $graph_height
|
||||
--width $graph_width ${!group}
|
||||
>
|
||||
EOF
|
||||
fi
|
||||
|
||||
if [ "$graph_weekly" -ne 0 ] ; then
|
||||
cat << EOF
|
||||
<RRD::GRAPH "$img_dir/$hostname-$group-weekly.gif"
|
||||
--imginfo "<img src="$web_dir/%s" width="%lu" height="%lu">"
|
||||
--lazy
|
||||
--start -7d
|
||||
--vertical-label "${!group_unit}"
|
||||
--title "Weelky graph"
|
||||
--height $graph_height
|
||||
--width $graph_width ${!group}
|
||||
>
|
||||
EOF
|
||||
fi
|
||||
|
||||
if [ "$graph_monthly" -ne 0 ] ; then
|
||||
cat << EOF
|
||||
<RRD::GRAPH "$img_dir/$hostname-$group-monthly.gif"
|
||||
--imginfo "<img src="$web_dir/%s" width="%lu" height="%lu">"
|
||||
--lazy
|
||||
--start -30d
|
||||
--vertical-label "${!group_unit}"
|
||||
--title "Monthly graph"
|
||||
--height $graph_height
|
||||
--width $graph_width ${!group}
|
||||
>
|
||||
EOF
|
||||
fi
|
||||
done
|
||||
|
||||
cat << EOF
|
||||
</body>
|
||||
</html>
|
||||
EOF
|
@ -1,3 +1,19 @@
|
||||
ipmitool (1.5.9) unstable; urgency=low
|
||||
|
||||
* Add ability to get a particular sensor by name
|
||||
* Add ability to set a particular sensor threshold
|
||||
* Add support for displaying V2 channel authentication levels
|
||||
* Add README for rrdtool scripts in contrib directory
|
||||
* Improve lan interface retry handling
|
||||
* Support prompting for password or reading from environment
|
||||
* Move chaninfo command into channel subcommand
|
||||
* Fix reservation ID handling when two sessions open to BMC
|
||||
* Fix reading of large FRU data
|
||||
* Add configure option for changing binary to ipmiadm for Solaris
|
||||
* Fix compile problem on Solaris 8
|
||||
|
||||
-- Duncan Laurie <duncan@sun.com> Sat, 27 Mar 2004 00:11:37 -0700
|
||||
|
||||
ipmitool (1.5.8) unstable; urgency=low
|
||||
|
||||
* Enable static compilation of interfaces
|
||||
|
3
ipmitool/debian/docs
Normal file
3
ipmitool/debian/docs
Normal file
@ -0,0 +1,3 @@
|
||||
COPYING
|
||||
AUTHORS
|
||||
ChangeLog
|
@ -82,7 +82,7 @@ binary-common:
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
# dh_installdebconf
|
||||
# dh_installdocs
|
||||
dh_installdocs
|
||||
# dh_installexamples
|
||||
# dh_installmenu
|
||||
# dh_installemacsen
|
||||
|
@ -32,8 +32,20 @@
|
||||
# in the design, construction, operation or maintenance of any nuclear
|
||||
# facility.
|
||||
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
MAINTAINERCLEANFILES = Makefile.in ipmitool.1
|
||||
|
||||
man_MANS = ipmitool.1
|
||||
EXTRA_DIST = ipmitool.1.in
|
||||
|
||||
install-data-hook:
|
||||
if test @IPMITOOL_BIN@ != ipmitool && \
|
||||
test -e $(mandir)/man1/ipmitool.1 ; then \
|
||||
mv -f $(mandir)/man1/ipmitool.1 $(mandir)/man1/@IPMITOOL_BIN@.1 ; \
|
||||
fi
|
||||
|
||||
uninstall-hook:
|
||||
if test @IPMITOOL_BIN@ != ipmitool && \
|
||||
test -e $(mandir)/man1/@IPMITOOL_BIN@.1 ; then \
|
||||
mv -f $(mandir)/man1/@IPMITOOL_BIN@.1 $(mandir)/man1/ipmitool.1 ; \
|
||||
fi
|
||||
|
||||
EXTRA_DIST = $(man_MANS)
|
||||
|
@ -1,12 +1,12 @@
|
||||
.TH "ipmitool" "1" "" "Duncan Laurie" ""
|
||||
.TH "@IPMITOOL_BIN@" "1" "" "Duncan Laurie" ""
|
||||
.SH "NAME"
|
||||
.LP
|
||||
ipmitool \- utility for controlling IPMI-enabled devices
|
||||
@IPMITOOL_BIN@ \- utility for controlling IPMI-enabled devices
|
||||
.SH "SYNTAX"
|
||||
.LP
|
||||
ipmitool [\fB\-ghcvV\fR] \fB\-I\fR \fIlan\fP \fB\-H\fR \fIhostname\fP [\fB\-P\fR \fIpassword\fP] <\fIexpression\fP>
|
||||
@IPMITOOL_BIN@ [\fB\-ghcvV\fR] \fB\-I\fR \fIlan\fP \fB\-H\fR \fIhostname\fP [\fB\-a\fR|\fB\-E\fR|\fB\-P\fR \fIpassword\fP] <\fIexpression\fP>
|
||||
.br
|
||||
ipmitool [\fB\-ghcvV\fR] \fB\-I\fR \fIopen\fP <\fIexpression\fP>
|
||||
@IPMITOOL_BIN@ [\fB\-ghcvV\fR] \fB\-I\fR \fIopen\fP <\fIexpression\fP>
|
||||
.SH "DESCRIPTION"
|
||||
.LP
|
||||
This program lets you perform various IPMI functions with either a kernel device driver or over a LAN interface. These functions include printing FRU information, LAN configuration, sensor readings, and remote chassis power control.
|
||||
@ -34,29 +34,35 @@ Selects IPMI interface to use. Possible interfaces are \fIlan\fP or \fIopen\fP.
|
||||
\fB\-H\fR <\fIaddress\fP>
|
||||
Remote server address, can be IP address or hostname. This option is required for the LAN interface connection.
|
||||
.TP
|
||||
\fB\-P\fR <\fIpassword\fP>
|
||||
Remote server password, 16 character maximum. This is optional for the LAN interface, if it is not provided the session will not be authenticated.
|
||||
.TP
|
||||
\fB\-U\fR <\fIusername\fP>
|
||||
Remote username, default is NULL user.
|
||||
.TP
|
||||
\fB\-a\fR
|
||||
Promt for the remote server password, 16 character maximum. This is optional for the LAN interface, if a password is not provided the session will not be authenticated.
|
||||
.TP
|
||||
\fB\-E\fR
|
||||
The remote server password is specified by the environment variable \fBIPMI_PASSWORD\fR. This option is intended for shell scripts.
|
||||
.TP
|
||||
\fB\-P\fR <\fIpassword\fP>
|
||||
Remote server password. \fBNote!\fR Specifying the password as a commandline option is not recommended since it will be visible in the process list.
|
||||
.SH "EXPRESSIONS"
|
||||
.LP
|
||||
.TP
|
||||
.I help
|
||||
This can be used to get command-line help on ipmitool commands. It may also be placed at the end of commands to get option usage help.
|
||||
This can be used to get command-line help on @IPMITOOL_BIN@ commands. It may also be placed at the end of commands to get option usage help.
|
||||
.RS
|
||||
.PP
|
||||
ipmitool -I open help
|
||||
@IPMITOOL_BIN@ -I open help
|
||||
.br
|
||||
Commands: chassis, fru, lan, sdr, sel
|
||||
Commands: bmc, chassis, event, fru, lan, raw, sdr, sel, sensor, sol, userinfo, channel
|
||||
.LP
|
||||
.PP
|
||||
ipmitool -I open chassis help
|
||||
@IPMITOOL_BIN@ -I open chassis help
|
||||
.br
|
||||
Chassis Commands: status, power, identify, policy, restart_cause
|
||||
Chassis Commands: status, power, identify, policy, restart_cause, poh
|
||||
.LP
|
||||
.PP
|
||||
ipmitool -I open chassis power help
|
||||
@IPMITOOL_BIN@ -I open chassis power help
|
||||
.br
|
||||
Chassis Power Commands: status, on, off, cycle, reset, diag, soft
|
||||
.LP
|
||||
@ -66,7 +72,7 @@ Chassis Power Commands: status, on, off, cycle, reset, diag, soft
|
||||
This will allow you to execute raw IPMI commands. For example to query the POH counter with a raw command:
|
||||
.RS
|
||||
.PP
|
||||
ipmitool -I open raw 0x0 0xf
|
||||
@IPMITOOL_BIN@ -v -I open raw 0x0 0xf
|
||||
.br
|
||||
RAW REQ (netfn=0x0 cmd=0xf data_len=0)
|
||||
.br
|
||||
@ -76,11 +82,32 @@ RAW RSP (5 bytes)
|
||||
.LP
|
||||
.RE
|
||||
.TP
|
||||
\fIchaninfo\fP [\fBchannel\fR]
|
||||
.I channel
|
||||
.RS
|
||||
.TP
|
||||
\fIauthcap\fP <\fBchannel number\fR> <\fBmax priv\fR>
|
||||
This command will display information about the authentication capabilities of the slected channel at the specified privelige level.
|
||||
.RS
|
||||
.TP
|
||||
Possible privelige levels are:
|
||||
.br
|
||||
1 Callback level
|
||||
.br
|
||||
2 User level
|
||||
.br
|
||||
3 Operator level
|
||||
.br
|
||||
4 Administrator level
|
||||
.br
|
||||
5 OEM Proprietary level
|
||||
.LP
|
||||
.RE
|
||||
.TP
|
||||
\fIinfo\fP [\fBchannel number\fR]
|
||||
This command will display information about the selected channel. If no channel is given it will display information about the currently used channel:
|
||||
.RS
|
||||
.PP
|
||||
ipmitool -I open chaninfo
|
||||
@IPMITOOL_BIN@ -I open chaninfo
|
||||
.br
|
||||
Channel 0xf info:
|
||||
.br
|
||||
@ -95,12 +122,13 @@ Channel 0xf info:
|
||||
Protocol Vendor ID : 7154
|
||||
.LP
|
||||
.RE
|
||||
.RE
|
||||
.TP
|
||||
\fIuserinfo\fP <\fBchannel\fR>
|
||||
This command will display information about configured user information on a specific LAN channel. This command will fail on system interfaces. Try channel 6 or 7.
|
||||
.RS
|
||||
.PP
|
||||
ipmitool -I open userinfo 6
|
||||
@IPMITOOL_BIN@ -I open userinfo 6
|
||||
.br
|
||||
Maximum User IDs : 4
|
||||
.br
|
||||
@ -267,6 +295,36 @@ This command will read all Field Replacable Unit inventory data and extract such
|
||||
This command will read the SDR and extract sensor information, then query each sensor and print its name, reading, and status.
|
||||
.RE
|
||||
.TP
|
||||
.I sensor
|
||||
.RS
|
||||
.TP
|
||||
.I list
|
||||
This command will list sensors and thresholds in a wide table format.
|
||||
.TP
|
||||
\fIget\fP <\fBid\fR> ... [\fBid\fR]
|
||||
This command will print info for sensors specified by name.
|
||||
.TP
|
||||
\fIthresh\fP <\fBid\fR> <\fBthreshold\fR> <\fBsetting\fR>
|
||||
This allows you to set a particular sensor threshold value. The sensor is specified by name.
|
||||
.RS
|
||||
.TP
|
||||
Valid thresholds are:
|
||||
.br
|
||||
unr Upper Non-Recoverable
|
||||
.br
|
||||
ucr Upper Critical
|
||||
.br
|
||||
unc Uperr Non-Critical
|
||||
.br
|
||||
lnc Lower Non-Critical
|
||||
.br
|
||||
lcr Lower Critical
|
||||
.br
|
||||
lnr Lower Non-Recoverable
|
||||
.LP
|
||||
.RE
|
||||
.RE
|
||||
.TP
|
||||
.I sel
|
||||
.RS
|
||||
.TP
|
||||
@ -288,9 +346,9 @@ Setup Serial-over-LAN: enable, set authentication and baud rate.
|
||||
.RE
|
||||
.SH "OPEN INTERFACE"
|
||||
.LP
|
||||
The ipmitool \fIopen\fP interface utilizes the MontaVista OpenIPMI kernel device driver. This driver is present in 2.5.57 and later development kernels and in 2.4.21pre1 and later stable kernels. There are also IPMI driver kernel patches for different versions available from the OpenIPMI homepage.
|
||||
The @IPMITOOL_BIN@ \fIopen\fP interface utilizes the MontaVista OpenIPMI kernel device driver. This driver is present in 2.5.57 and later development kernels and in 2.4.21pre1 and later stable kernels. There are also IPMI driver kernel patches for different versions available from the OpenIPMI homepage.
|
||||
.LP
|
||||
The following kernel modules must be loaded in order for ipmitool to work:
|
||||
The following kernel modules must be loaded in order for @IPMITOOL_BIN@ to work:
|
||||
.TP
|
||||
.B ipmi_msghandler
|
||||
Incoming and outgoing message handler for IPMI interfaces.
|
||||
@ -305,22 +363,22 @@ Once they are loaded there will be a dynamic char device entry that must exist a
|
||||
.LP
|
||||
.I mknod /dev/ipmi0 c 254 0
|
||||
.LP
|
||||
In order to force ipmitool to make use of the device interface you can specifiy it on the command line:
|
||||
In order to force @IPMITOOL_BIN@ to make use of the device interface you can specifiy it on the command line:
|
||||
.PP
|
||||
ipmitool \-I open <expression>
|
||||
@IPMITOOL_BIN@ \-I open <expression>
|
||||
.SH "LAN INTERFACE"
|
||||
.LP
|
||||
The ipmitool \fIlan\fP interface communicates with the BMC over an Ethernet LAN connection using UDP under IPv4. UDP datagrams are formatted to contain IPMI request/response messages with a IPMI session headers and RMCP headers.
|
||||
The @IPMITOOL_BIN@ \fIlan\fP interface communicates with the BMC over an Ethernet LAN connection using UDP under IPv4. UDP datagrams are formatted to contain IPMI request/response messages with a IPMI session headers and RMCP headers.
|
||||
.LP
|
||||
IPMI\-over\-LAN uses version 1 of the Remote Management Control Protocol (RMCP) to support \fIpre\-OS\fP and \fIOS\-absent\fP management. RMCP is a request\-response protocol delivered using UDP datagrams to port 623.
|
||||
.LP
|
||||
The LAN interface is an authenticatiod multi\-session connection; messages delivered to the BMC can (and should) be authenticated with a challenge/response protocol with either straight password/key or MD5 message\-digest algorithm. ipmitool will attempt to connect with administrator privilege level as this is required to perform chassis power functions.
|
||||
The LAN interface is an authenticatiod multi\-session connection; messages delivered to the BMC can (and should) be authenticated with a challenge/response protocol with either straight password/key or MD5 message\-digest algorithm. @IPMITOOL_BIN@ will attempt to connect with administrator privilege level as this is required to perform chassis power functions.
|
||||
.LP
|
||||
You can tell ipmitool to use the lan interface with the \fB\-I\fR option:
|
||||
You can tell @IPMITOOL_BIN@ to use the lan interface with the \fB\-I\fR option:
|
||||
.PP
|
||||
ipmitool \-I lan \-H <hostname> \-P [password] <expression>
|
||||
@IPMITOOL_BIN@ \-I lan \-H <hostname> \-P [password] <expression>
|
||||
.LP
|
||||
A hostname \fBmust\fR be given on the command line in order to use the lan interface with ipmitool. The password field is optional; if you do not provide a password on the command line ipmitool will attempt to connect without authentication. If you specify a password it will use MD5 authentication if supported by the BMC and straight password/key otherwise.
|
||||
A hostname \fBmust\fR be given on the command line in order to use the lan interface with @IPMITOOL_BIN@. The password field is optional; if you do not provide a password on the command line @IPMITOOL_BIN@ will attempt to connect without authentication. If you specify a password it will use MD5 authentication if supported by the BMC and straight password/key otherwise.
|
||||
.SH "FILES"
|
||||
.TP
|
||||
.I /dev/ipmi0
|
||||
@ -329,11 +387,11 @@ This character device file is used by the OpenIPMI kernel driver.
|
||||
.LP
|
||||
If you want to remotely control the power of an IPMI\-over\-LAN enabled system you can use:
|
||||
.LP
|
||||
ipmitool \-I lan \-H 192.168.1.1 \-P password chassis power on
|
||||
@IPMITOOL_BIN@ \-I lan \-H 192.168.1.1 \-P password chassis power on
|
||||
.br
|
||||
Chassis Power Control: Up/On
|
||||
.LP
|
||||
ipmitool \-I lan \-H 192.168.1.1 \-P password chassis power status
|
||||
@IPMITOOL_BIN@ \-I lan \-H 192.168.1.1 \-P password chassis power status
|
||||
.br
|
||||
Chassis Power is on
|
||||
.SH "AUTHOR"
|
||||
@ -350,3 +408,4 @@ http://www.intel.com/design/servers/ipmi/spec.htm
|
||||
.TP
|
||||
OpenIPMI project (MontaVista IPMI kernel driver)
|
||||
http://openipmi.sourceforge.net
|
||||
|
@ -38,5 +38,6 @@ ipmitooldir = $(includedir)/ipmitool
|
||||
|
||||
ipmitool_HEADERS = bswap.h helper.h ipmi.h ipmi_intf.h \
|
||||
ipmi_chassis.h ipmi_entity.h ipmi_fru.h ipmi_lanp.h \
|
||||
ipmi_sdr.h ipmi_sel.h ipmi_sol.h ipmi_bmc.h ipmi_sensor.h
|
||||
ipmi_sdr.h ipmi_sel.h ipmi_sol.h ipmi_bmc.h \
|
||||
ipmi_channel.h ipmi_sensor.h
|
||||
|
||||
|
@ -45,8 +45,6 @@
|
||||
# include <byteswap.h>
|
||||
# define BSWAP_16(x) bswap_16(x)
|
||||
# define BSWAP_32(x) bswap_32(x)
|
||||
#elif HAVE_SYS_BYTEORDER_H
|
||||
# include <sys/byteorder.h>
|
||||
#else
|
||||
# define BSWAP_16(x) ((((x) & 0xff00) >> 8) | (((x) & 0x00ff) << 8))
|
||||
# define BSWAP_32(x) ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) |\
|
||||
|
@ -37,7 +37,7 @@
|
||||
#ifndef IPMI_HELPER_H
|
||||
#define IPMI_HELPER_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
struct valstr {
|
||||
unsigned short val;
|
||||
|
@ -39,7 +39,7 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
#include <netinet/in.h>
|
||||
#include <ipmitool/helper.h>
|
||||
|
||||
|
176
ipmitool/include/ipmitool/ipmi_channel.h
Normal file
176
ipmitool/include/ipmitool/ipmi_channel.h
Normal file
@ -0,0 +1,176 @@
|
||||
/*
|
||||
* 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_CHANNEL_H
|
||||
#define IPMI_CHANNEL_H
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
#include <ipmitool/ipmi.h>
|
||||
|
||||
#define IPMI_GET_CHANNEL_AUTH_CAP 0x38
|
||||
#define IPMI_GET_CHANNEL_ACCESS 0x41
|
||||
#define IPMI_GET_CHANNEL_INFO 0x42
|
||||
|
||||
|
||||
#define IPMI_1_5_AUTH_TYPE_BIT_NONE 0x01
|
||||
#define IPMI_1_5_AUTH_TYPE_BIT_MD2 0x02
|
||||
#define IPMI_1_5_AUTH_TYPE_BIT_MD5 0x04
|
||||
#define IPMI_1_5_AUTH_TYPE_BIT_PASSWORD 0x10
|
||||
#define IPMI_1_5_AUTH_TYPE_BIT_OEM 0x20
|
||||
|
||||
|
||||
/*
|
||||
* The Get Authentication Capabilities response structure
|
||||
* From table 22-15 of the IPMI v2.0 spec
|
||||
*/
|
||||
struct get_channel_auth_cap_rsp {
|
||||
unsigned char channel_number;
|
||||
#if WORDS_BIGENDIAN
|
||||
unsigned char v20_data_available : 1; /* IPMI v2.0 data is available */
|
||||
unsigned char __reserved1 : 1;
|
||||
unsigned char enabled_auth_types : 6; /* IPMI v1.5 enabled auth types */
|
||||
#else
|
||||
unsigned char enabled_auth_types : 6; /* IPMI v1.5 enabled auth types */
|
||||
unsigned char __reserved1 : 1;
|
||||
unsigned char v20_data_available : 1; /* IPMI v2.0 data is available */
|
||||
#endif
|
||||
#if WORDS_BIGENDIAN
|
||||
unsigned char __reserved2 : 2;
|
||||
unsigned char kg_status : 1; /* two-key login status */
|
||||
unsigned char per_message_auth : 1; /* per-message authentication status */
|
||||
unsigned char user_level_auth : 1; /* user-level authentication status */
|
||||
unsigned char non_null_usernames : 1; /* one or more non-null users exist */
|
||||
unsigned char null_usernames : 1; /* one or more null usernames non-null pwds */
|
||||
unsigned char anon_login_enabled : 1; /* a null-named, null-pwd user exists */
|
||||
#else
|
||||
unsigned char anon_login_enabled : 1; /* a null-named, null-pwd user exists */
|
||||
unsigned char null_usernames : 1; /* one or more null usernames non-null pwds */
|
||||
unsigned char non_null_usernames : 1; /* one or more non-null users exist */
|
||||
unsigned char user_level_auth : 1; /* user-level authentication status */
|
||||
unsigned char per_message_auth : 1; /* per-message authentication status */
|
||||
unsigned char kg_status : 1; /* two-key login status */
|
||||
unsigned char __reserved2 : 2;
|
||||
#endif
|
||||
#if WORDS_BIGENDIAN
|
||||
unsigned char __reserved3 : 6;
|
||||
unsigned char ipmiv15_support : 1; /* channel supports IPMI v1.5 connections */
|
||||
unsigned char ipmiv20_support : 1; /* channel supports IPMI v2.0 connections */
|
||||
#else
|
||||
unsigned char ipmiv20_support : 1; /* channel supports IPMI v2.0 connections */
|
||||
unsigned char ipmiv15_support : 1; /* channel supports IPMI v1.5 connections */
|
||||
unsigned char __reserved3 : 6;
|
||||
#endif
|
||||
unsigned char oem_id[3]; /* IANA enterprise number for auth type */
|
||||
unsigned char oem_aux_data; /* Additional OEM specific data for oem auths */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* The Get Channel Info response structure
|
||||
* From table 22-29 of the IPMI v2.0 spec
|
||||
*/
|
||||
struct get_channel_info_rsp {
|
||||
#if WORDS_BIGENDIAN
|
||||
unsigned char __reserved1 : 4;
|
||||
unsigned char channel_number : 4; /* channel number */
|
||||
#else
|
||||
unsigned char channel_number : 4; /* channel number */
|
||||
unsigned char __reserved1 : 4;
|
||||
#endif
|
||||
#if WORDS_BIGENDIAN
|
||||
unsigned char __reserved2 : 1;
|
||||
unsigned char channel_medium : 7; /* Channel medium type per table 6-3 */
|
||||
#else
|
||||
unsigned char channel_medium : 7; /* Channel medium type per table 6-3 */
|
||||
unsigned char __reserved2 : 1;
|
||||
#endif
|
||||
#if WORDS_BIGENDIAN
|
||||
unsigned char __reserved3 : 3;
|
||||
unsigned char channel_protocol : 5; /* Channel protocol per table 6-2 */
|
||||
#else
|
||||
unsigned char channel_protocol : 5; /* Channel protocol per table 6-2 */
|
||||
unsigned char __reserved3 : 3;
|
||||
#endif
|
||||
#if WORDS_BIGENDIAN
|
||||
unsigned char session_support : 2; /* Description of session support */
|
||||
unsigned char active_sessions : 6; /* Count of active sessions */
|
||||
#else
|
||||
unsigned char active_sessions : 6; /* Count of active sessions */
|
||||
unsigned char session_support : 2; /* Description of session support */
|
||||
#endif
|
||||
unsigned char vendor_id[3]; /* For OEM that specified the protocol */
|
||||
unsigned char aux_info[2]; /* Not used*/
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* The Get Channel Access response structure
|
||||
* From table 22-28 of the IPMI v2.0 spec
|
||||
*/
|
||||
struct get_channel_access_rsp {
|
||||
#if WORDS_BIGENDIAN
|
||||
unsigned char __reserved1 : 2;
|
||||
unsigned char alerting : 1;
|
||||
unsigned char per_message_auth : 1;
|
||||
unsigned char user_level_auth : 1;
|
||||
unsigned char access_mode : 3;
|
||||
#else
|
||||
unsigned char access_mode : 3;
|
||||
unsigned char user_level_auth : 1;
|
||||
unsigned char per_message_auth : 1;
|
||||
unsigned char alerting : 1;
|
||||
unsigned char __reserved1 : 2;
|
||||
#endif
|
||||
#if WORDS_BIGENDIAN
|
||||
unsigned char __reserved2 : 4;
|
||||
unsigned char channel_priv_limit : 4; /* Channel privilege level limit */
|
||||
#else
|
||||
unsigned char channel_priv_limit : 4; /* Channel privilege level limit */
|
||||
unsigned char __reserved2 : 4;
|
||||
#endif
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
|
||||
int ipmi_channel_main(struct ipmi_intf *, int, char **);
|
||||
void ipmi_get_channel_auth_cap(struct ipmi_intf * intf, unsigned char channel, unsigned char priv);
|
||||
void ipmi_get_channel_info(struct ipmi_intf * intf, unsigned char channel);
|
||||
|
||||
#endif /*IPMI_CHANNEL_H*/
|
@ -37,7 +37,7 @@
|
||||
#ifndef IPMI_FRU_H
|
||||
#define IPMI_FRU_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
#include <ipmitool/ipmi.h>
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
|
@ -128,7 +128,6 @@ static struct lan_param {
|
||||
{ -1 }
|
||||
};
|
||||
|
||||
void ipmi_get_channel_info(struct ipmi_intf * intf, unsigned char channel);
|
||||
int ipmi_lanp_main(struct ipmi_intf *, int, char **);
|
||||
|
||||
#endif /*IPMI_LANP_H*/
|
||||
|
@ -41,7 +41,7 @@
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
#include <math.h>
|
||||
#include <ipmitool/bswap.h>
|
||||
#include <ipmitool/ipmi.h>
|
||||
@ -98,7 +98,6 @@ struct sdr_get_rq {
|
||||
unsigned short id; /* record ID */
|
||||
unsigned char offset; /* offset into SDR */
|
||||
#define GET_SDR_ENTIRE_RECORD 0xff
|
||||
#define GET_SDR_MAX_LEN 30
|
||||
unsigned char length; /* length to read */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
@ -577,6 +576,19 @@ struct ipmi_sdr_iterator
|
||||
int next;
|
||||
};
|
||||
|
||||
struct sdr_record_list {
|
||||
unsigned short id;
|
||||
unsigned char type;
|
||||
struct sdr_record_list * next;
|
||||
union {
|
||||
struct sdr_record_full_sensor * full;
|
||||
struct sdr_record_compact_sensor * compact;
|
||||
struct sdr_record_eventonly_sensor * eventonly;
|
||||
struct sdr_record_fru_locator * fruloc;
|
||||
struct sdr_record_mc_locator * mcloc;
|
||||
} record;
|
||||
};
|
||||
|
||||
/* unit description codes (IPMI v1.5 section 37.16) */
|
||||
#define UNIT_MAX 0x90
|
||||
static const char * unit_desc[] __attribute__((unused)) = {
|
||||
@ -627,7 +639,17 @@ void ipmi_sdr_end(struct ipmi_intf * intf, struct ipmi_sdr_iterator * i);
|
||||
void ipmi_sdr_print_sdr(struct ipmi_intf * intf, unsigned char type);
|
||||
const char * ipmi_sdr_get_status(unsigned char stat);
|
||||
float sdr_convert_sensor_reading(struct sdr_record_full_sensor * sensor, unsigned char val);
|
||||
unsigned char sdr_convert_sensor_value_to_raw(struct sdr_record_full_sensor * sensor, float val);
|
||||
struct ipmi_rs * ipmi_sdr_get_sensor_reading(struct ipmi_intf * intf, unsigned char sensor);
|
||||
const char * ipmi_sdr_get_sensor_type_desc(const unsigned char type);
|
||||
|
||||
void ipmi_sdr_print_sensor_full(struct ipmi_intf * intf, struct sdr_record_full_sensor * sensor);
|
||||
void ipmi_sdr_print_sensor_compact(struct ipmi_intf * intf, struct sdr_record_compact_sensor * sensor);
|
||||
void ipmi_sdr_print_sensor_eventonly(struct ipmi_intf * intf, struct sdr_record_eventonly_sensor * sensor);
|
||||
void ipmi_sdr_print_fru_locator(struct ipmi_intf * intf, struct sdr_record_fru_locator * fru);
|
||||
void ipmi_sdr_print_mc_locator(struct ipmi_intf * intf, struct sdr_record_mc_locator * mc);
|
||||
|
||||
struct sdr_record_list * ipmi_sdr_find_sdr_byid(struct ipmi_intf * intf, char * id);
|
||||
void ipmi_sdr_list_empty(struct ipmi_intf * intf);
|
||||
|
||||
#endif /* IPMI_SDR_H */
|
||||
|
@ -37,7 +37,7 @@
|
||||
#ifndef IPMI_SEL_H
|
||||
#define IPMI_SEL_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
#include <ipmitool/ipmi.h>
|
||||
|
||||
#define IPMI_CMD_GET_SEL_INFO 0x40
|
||||
|
@ -41,11 +41,54 @@
|
||||
#include <ipmitool/bswap.h>
|
||||
#include <ipmitool/ipmi.h>
|
||||
|
||||
/* ipmi sensor commands */
|
||||
#define GET_SENSOR_READING 0x2d
|
||||
#define GET_SENSOR_FACTORS 0x23
|
||||
#define GET_SENSOR_THRES 0x27
|
||||
#define SET_SENSOR_THRESHOLDS 0x26
|
||||
#define GET_SENSOR_THRESHOLDS 0x27
|
||||
#define GET_SENSOR_TYPE 0x2f
|
||||
|
||||
/* threshold specification bits for analog sensors for get sensor threshold command
|
||||
* and set sensor threshold command
|
||||
*/
|
||||
#define UPPER_NON_RECOV_SPECIFIED 0x20
|
||||
#define UPPER_CRIT_SPECIFIED 0x10
|
||||
#define UPPER_NON_CRIT_SPECIFIED 0x08
|
||||
#define LOWER_NON_RECOV_SPECIFIED 0x04
|
||||
#define LOWER_CRIT_SPECIFIED 0x02
|
||||
#define LOWER_NON_CRIT_SPECIFIED 0x01
|
||||
|
||||
/* state assertion bits for discrete sensors for get sensor reading command */
|
||||
#define STATE_0_ASSERTED 0x01
|
||||
#define STATE_1_ASSERTED 0x02
|
||||
#define STATE_2_ASSERTED 0x04
|
||||
#define STATE_3_ASSERTED 0x08
|
||||
#define STATE_4_ASSERTED 0x10
|
||||
#define STATE_5_ASSERTED 0x20
|
||||
#define STATE_6_ASSERTED 0x40
|
||||
#define STATE_7_ASSERTED 0x80
|
||||
#define STATE_8_ASSERTED 0x01
|
||||
#define STATE_9_ASSERTED 0x02
|
||||
#define STATE_10_ASSERTED 0x04
|
||||
#define STATE_11_ASSERTED 0x08
|
||||
#define STATE_12_ASSERTED 0x10
|
||||
#define STATE_13_ASSERTED 0x20
|
||||
#define STATE_14_ASSERTED 0x40
|
||||
|
||||
struct sensor_set_thresh_rq {
|
||||
unsigned char sensor_num; /* sensor # */
|
||||
unsigned char set_mask; /* threshold setting mask */
|
||||
unsigned char lower_non_crit; /* new lower non critical threshold*/
|
||||
unsigned char lower_crit; /* new lower critical threshold*/
|
||||
unsigned char lower_non_recov; /* new lower non recoverable threshold*/
|
||||
unsigned char upper_non_crit; /* new upper non critical threshold*/
|
||||
unsigned char upper_crit; /* new upper critical threshold*/
|
||||
unsigned char upper_non_recov; /* new upper non recoverable threshold*/
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
int ipmi_sensor_main(struct ipmi_intf *, int, char **);
|
||||
void ipmi_sensor_print_full(struct ipmi_intf *, struct sdr_record_full_sensor *);
|
||||
void ipmi_sensor_print_compact(struct ipmi_intf *, struct sdr_record_compact_sensor *);
|
||||
|
||||
#endif /* IPMI_SENSOR_H */
|
||||
|
@ -49,6 +49,12 @@ make
|
||||
%install
|
||||
make DESTDIR=$RPM_BUILD_ROOT install-strip
|
||||
|
||||
DOCDIR=$RPM_BUILD_ROOT%{_datadir}/doc/@IPMITOOL_PKG@-@VERSION@
|
||||
mkdir -p $DOCDIR
|
||||
for DOC in COPYING AUTHORS ChangeLog ; do
|
||||
install -m 644 -o root -g root $DOC $DOCDIR/$DOC
|
||||
done
|
||||
|
||||
%clean
|
||||
if [ "$RPM_BUILD_ROOT" ] && [ "$RPM_BUILD_ROOT" != "/" ]; then
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
@ -59,6 +65,7 @@ rm -rf $RPM_BUILD_DIR/@IPMITOOL_PKG@-@VERSION@
|
||||
%defattr(-,root,root)
|
||||
%doc %{_mandir}/man1/*
|
||||
%{_bindir}/*
|
||||
%{_datadir}/doc/@IPMITOOL_PKG@-@VERSION@/*
|
||||
|
||||
%files dev
|
||||
%defattr(-,root,root)
|
||||
@ -66,6 +73,19 @@ rm -rf $RPM_BUILD_DIR/@IPMITOOL_PKG@-@VERSION@
|
||||
%{_includedir}/ipmitool/*.h
|
||||
|
||||
%changelog
|
||||
* Sat May 27 2004 <duncan@sun.com> 1.5.9-1
|
||||
- Add ability to get a particular sensor by name
|
||||
- Add ability to set a particular sensor threshold
|
||||
- Add support for displaying V2 channel authentication levels
|
||||
- Add README for rrdtool scripts in contrib directory
|
||||
- Improve lan interface retry handling
|
||||
- Support prompting for password or reading from environment
|
||||
- Move chaninfo command into channel subcommand
|
||||
- Fix reservation ID handling when two sessions open to BMC
|
||||
- Fix reading of large FRU data
|
||||
- Add configure option for changing binary to ipmiadm for Solaris
|
||||
- Fix compile problem on Solaris 8
|
||||
|
||||
* Tue Jan 27 2004 <duncan@sun.com> 1.5.8-1
|
||||
- Enable static compilation of interfaces
|
||||
- Fix types to be 64-bit safe
|
||||
|
@ -37,7 +37,8 @@ MAINTAINERCLEANFILES = Makefile.in
|
||||
|
||||
noinst_LTLIBRARIES = libipmitool.la
|
||||
libipmitool_la_SOURCES = helper.c ipmi_sdr.c ipmi_sel.c ipmi_sol.c ipmi_lanp.c \
|
||||
ipmi_fru.c ipmi_chassis.c ipmi_bmc.c dimm_spd.c ipmi_sensor.c
|
||||
ipmi_fru.c ipmi_chassis.c ipmi_bmc.c dimm_spd.c ipmi_sensor.c \
|
||||
ipmi_channel.c
|
||||
libipmitool_la_LDFLAGS = -export-dynamic
|
||||
libipmitool_la_LIBADD = -lm
|
||||
libipmitool_la_DEPENDENCIES =
|
||||
|
@ -36,7 +36,7 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
#include <signal.h>
|
||||
#include <ipmitool/helper.h>
|
||||
|
||||
|
432
ipmitool/lib/ipmi_channel.c
Normal file
432
ipmitool/lib/ipmi_channel.c
Normal file
@ -0,0 +1,432 @@
|
||||
/*
|
||||
* 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 <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <ipmitool/ipmi.h>
|
||||
#include <ipmitool/helper.h>
|
||||
#include <ipmitool/ipmi_channel.h>
|
||||
|
||||
|
||||
|
||||
const struct valstr ipmi_authtype_vals[] = {
|
||||
{ IPMI_1_5_AUTH_TYPE_BIT_NONE, "NONE" },
|
||||
{ IPMI_1_5_AUTH_TYPE_BIT_MD2, "MD2" },
|
||||
{ IPMI_1_5_AUTH_TYPE_BIT_MD5, "MD5" },
|
||||
{ IPMI_1_5_AUTH_TYPE_BIT_PASSWORD, "PASSWORD" },
|
||||
{ IPMI_1_5_AUTH_TYPE_BIT_OEM, "OEM" },
|
||||
{ 0, NULL },
|
||||
};
|
||||
|
||||
|
||||
|
||||
static const struct valstr ipmi_channel_protocol_vals[] = {
|
||||
{ 0x00, "reserved" },
|
||||
{ 0x01, "IPMB-1.0" },
|
||||
{ 0x02, "ICMB-1.0" },
|
||||
{ 0x03, "reserved" },
|
||||
{ 0x04, "IPMI-SMBus" },
|
||||
{ 0x05, "KCS" },
|
||||
{ 0x06, "SMIC" },
|
||||
{ 0x07, "BT-10" },
|
||||
{ 0x08, "BT-15" },
|
||||
{ 0x09, "TMode" },
|
||||
{ 0x1c, "OEM 1" },
|
||||
{ 0x1d, "OEM 2" },
|
||||
{ 0x1e, "OEM 3" },
|
||||
{ 0x1f, "OEM 4" },
|
||||
{ 0x00, NULL },
|
||||
};
|
||||
|
||||
|
||||
static const struct valstr ipmi_channel_medium_vals[] = {
|
||||
{ 0x00, "reserved" },
|
||||
{ 0x01, "IPMB (I2C)" },
|
||||
{ 0x02, "ICMB v1.0" },
|
||||
{ 0x03, "ICMB v0.9" },
|
||||
{ 0x04, "802.3 LAN" },
|
||||
{ 0x05, "Serial/Modem" },
|
||||
{ 0x06, "Other LAN" },
|
||||
{ 0x07, "PCI SMBus" },
|
||||
{ 0x08, "SMBus v1.0/v1.1" },
|
||||
{ 0x09, "SMBus v2.0" },
|
||||
{ 0x0a, "USB 1.x" },
|
||||
{ 0x0b, "USB 2.x" },
|
||||
{ 0x0c, "System Interface" },
|
||||
{ 0x00, NULL },
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* ipmi_1_5_authtypes
|
||||
*
|
||||
* Create a string describing the supported authentication types as
|
||||
* specificed by the parameter n
|
||||
*/
|
||||
const char * ipmi_1_5_authtypes(unsigned char n)
|
||||
{
|
||||
unsigned int i;
|
||||
static char supportedTypes[128];
|
||||
|
||||
bzero(supportedTypes, 128);
|
||||
|
||||
i = 0;
|
||||
while (ipmi_authtype_vals[i].val)
|
||||
{
|
||||
if (n & ipmi_authtype_vals[i].val)
|
||||
{
|
||||
strcat(supportedTypes, ipmi_authtype_vals[i].str);
|
||||
strcat(supportedTypes, " ");
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
return supportedTypes;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* ipmi_get_channel_auth_cap
|
||||
*
|
||||
* Wrapper around the Get Channel Authentication Capabilities command
|
||||
*/
|
||||
void ipmi_get_channel_auth_cap(struct ipmi_intf * intf,
|
||||
unsigned char channel,
|
||||
unsigned char priv)
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
struct get_channel_auth_cap_rsp auth_cap;
|
||||
|
||||
|
||||
unsigned char msg_data[2];
|
||||
msg_data[0] = channel | 0x80; // Ask for IPMI v2 data as well
|
||||
msg_data[1] = priv;
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.msg.netfn = IPMI_NETFN_APP; // 0x06
|
||||
req.msg.cmd = IPMI_GET_CHANNEL_AUTH_CAP; // 0x38
|
||||
req.msg.data = msg_data;
|
||||
req.msg.data_len = 2;
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
|
||||
if (!rsp || rsp->ccode)
|
||||
{
|
||||
/*
|
||||
* It's very possible that this failed because we asked for IPMI v2 data
|
||||
* Ask again, without requesting IPMI v2 data
|
||||
*/
|
||||
msg_data[0] &= 0x7F;
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (!rsp || rsp->ccode) {
|
||||
printf("Error:%x Get Channel Authentication Capabilities Command (0x%x)\n",
|
||||
rsp ? rsp->ccode : 0, channel);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(&auth_cap, rsp->data, sizeof(struct get_channel_auth_cap_rsp));
|
||||
|
||||
|
||||
printf("Channel number : %d\n",
|
||||
auth_cap.channel_number);
|
||||
printf("IPMI v1.5 auth types : %s\n",
|
||||
ipmi_1_5_authtypes(auth_cap.enabled_auth_types));
|
||||
|
||||
if (auth_cap.v20_data_available)
|
||||
printf("KG status : %s\n",
|
||||
(auth_cap.kg_status) ? "non-zero" : "default (all zeroes)");
|
||||
|
||||
printf("Per message authentication : %sabled\n",
|
||||
(auth_cap.per_message_auth) ? "en" : "dis");
|
||||
printf("User level authentication : %sabled\n",
|
||||
(auth_cap.user_level_auth) ? "en" : "dis");
|
||||
|
||||
printf("Non-null user names exist : %s\n",
|
||||
(auth_cap.non_null_usernames) ? "yes" : "no");
|
||||
printf("Null user names exist : %s\n",
|
||||
(auth_cap.null_usernames) ? "yes" : "no");
|
||||
printf("Anonymous login enabled : %s\n",
|
||||
(auth_cap.anon_login_enabled) ? "yes" : "no");
|
||||
|
||||
if (auth_cap.v20_data_available)
|
||||
{
|
||||
printf("Channel supports IPMI v1.5 : %s\n",
|
||||
(auth_cap.ipmiv15_support) ? "yes" : "no");
|
||||
printf("Channel supports IPMI v2.0 : %s\n",
|
||||
(auth_cap.ipmiv20_support) ? "yes" : "no");
|
||||
}
|
||||
|
||||
/*
|
||||
* If there is support for an OEM authentication type, there is some
|
||||
* information.
|
||||
*/
|
||||
if (auth_cap.enabled_auth_types & IPMI_1_5_AUTH_TYPE_BIT_OEM)
|
||||
{
|
||||
printf("IANA Number for OEM : %d\n",
|
||||
auth_cap.oem_id[0] |
|
||||
auth_cap.oem_id[1] << 8 |
|
||||
auth_cap.oem_id[2] << 16);
|
||||
printf("OEM Auxiliary Data : 0x%x\n",
|
||||
auth_cap.oem_aux_data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* ipmi_get_channel_info
|
||||
*
|
||||
* Wrapper around the Get Channel Info command
|
||||
*/
|
||||
void
|
||||
ipmi_get_channel_info(struct ipmi_intf * intf, unsigned char channel)
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
unsigned char rqdata[2];
|
||||
struct get_channel_info_rsp channel_info;
|
||||
struct get_channel_access_rsp channel_access;
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.msg.netfn = IPMI_NETFN_APP; // 0x06
|
||||
req.msg.cmd = IPMI_GET_CHANNEL_INFO; // 0x42
|
||||
req.msg.data = &channel;
|
||||
req.msg.data_len = 1;
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
|
||||
if (!rsp || rsp->ccode) {
|
||||
printf("Error:%x Get Channel Info Command (0x%x)\n",
|
||||
rsp ? rsp->ccode : 0, channel);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
memcpy(&channel_info, rsp->data, sizeof(struct get_channel_info_rsp));
|
||||
|
||||
|
||||
printf("Channel 0x%x info:\n", channel_info.channel_number);
|
||||
|
||||
printf(" Channel Medium Type : %s\n",
|
||||
val2str(channel_info.channel_medium, ipmi_channel_medium_vals));
|
||||
|
||||
printf(" Channel Protocol Type : %s\n",
|
||||
val2str(channel_info.channel_protocol, ipmi_channel_protocol_vals));
|
||||
|
||||
printf(" Session Support : ");
|
||||
switch (channel_info.session_support) {
|
||||
case 0x00:
|
||||
printf("session-less\n");
|
||||
break;
|
||||
case 0x40:
|
||||
printf("single-session\n");
|
||||
break;
|
||||
case 0x80:
|
||||
printf("multi-session\n");
|
||||
break;
|
||||
case 0xc0:
|
||||
default:
|
||||
printf("session-based\n");
|
||||
break;
|
||||
}
|
||||
|
||||
printf(" Active Session Count : %d\n",
|
||||
channel_info.active_sessions);
|
||||
|
||||
printf(" Protocol Vendor ID : %d\n",
|
||||
channel_info.vendor_id[0] |
|
||||
channel_info.vendor_id[1] << 8 |
|
||||
channel_info.vendor_id[2] << 16);
|
||||
|
||||
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
rqdata[0] = channel & 0xf;
|
||||
|
||||
/* get volatile settings */
|
||||
|
||||
rqdata[1] = 0x80; /* 0x80=active */
|
||||
req.msg.netfn = IPMI_NETFN_APP; // 0x06
|
||||
req.msg.cmd = IPMI_GET_CHANNEL_ACCESS; // 0x41
|
||||
req.msg.data = rqdata;
|
||||
req.msg.data_len = 2;
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (!rsp || rsp->ccode) {
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(&channel_access, rsp->data, sizeof(struct get_channel_access_rsp));
|
||||
|
||||
|
||||
printf(" Volatile(active) Settings\n");
|
||||
printf(" Alerting : %sabled\n",
|
||||
(channel_access.alerting) ? "dis" : "en");
|
||||
printf(" Per-message Auth : %sabled\n",
|
||||
(channel_access.per_message_auth) ? "dis" : "en");
|
||||
printf(" User Level Auth : %sabled\n",
|
||||
(channel_access.user_level_auth) ? "dis" : "en");
|
||||
|
||||
printf(" Access Mode : ");
|
||||
switch (channel_access.access_mode) {
|
||||
case 0:
|
||||
printf("disabled\n");
|
||||
break;
|
||||
case 1:
|
||||
printf("pre-boot only\n");
|
||||
break;
|
||||
case 2:
|
||||
printf("always available\n");
|
||||
break;
|
||||
case 3:
|
||||
printf("shared\n");
|
||||
break;
|
||||
default:
|
||||
printf("unknown\n");
|
||||
break;
|
||||
}
|
||||
|
||||
/* get non-volatile settings */
|
||||
|
||||
rqdata[1] = 0x40; /* 0x40=non-volatile */
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (!rsp || rsp->ccode) {
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(&channel_access, rsp->data, sizeof(struct get_channel_access_rsp));
|
||||
|
||||
printf(" Non-Volatile Settings\n");
|
||||
printf(" Alerting : %sabled\n",
|
||||
(channel_access.alerting) ? "dis" : "en");
|
||||
printf(" Per-message Auth : %sabled\n",
|
||||
(channel_access.per_message_auth) ? "dis" : "en");
|
||||
printf(" User Level Auth : %sabled\n",
|
||||
(channel_access.user_level_auth) ? "dis" : "en");
|
||||
|
||||
printf(" Access Mode : ");
|
||||
switch (channel_access.access_mode) {
|
||||
case 0:
|
||||
printf("disabled\n");
|
||||
break;
|
||||
case 1:
|
||||
printf("pre-boot only\n");
|
||||
break;
|
||||
case 2:
|
||||
printf("always available\n");
|
||||
break;
|
||||
case 3:
|
||||
printf("shared\n");
|
||||
break;
|
||||
default:
|
||||
printf("unknown\n");
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
printf_channel_usage()
|
||||
{
|
||||
printf("Channel Commands: authcap <channel number> <max priv>\n");
|
||||
printf(" info [channel number]\n");
|
||||
printf("\n");
|
||||
printf("Possible privelige levels are:\n");
|
||||
printf(" 1 Callback level\n");
|
||||
printf(" 2 User level\n");
|
||||
printf(" 3 Operator level\n");
|
||||
printf(" 4 Administrator level\n");
|
||||
printf(" 5 OEM Proprietary level\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
ipmi_channel_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
{
|
||||
int retval = 0;
|
||||
|
||||
if (!argc || !strncmp(argv[0], "help", 4))
|
||||
printf_channel_usage();
|
||||
|
||||
else if (!strncmp(argv[0], "authcap", 7))
|
||||
{
|
||||
if (argc != 3)
|
||||
printf_channel_usage();
|
||||
else
|
||||
ipmi_get_channel_auth_cap(intf,
|
||||
(unsigned char)strtol(argv[1], NULL, 0),
|
||||
(unsigned char)strtol(argv[2], NULL, 0));
|
||||
}
|
||||
else if (!strncmp(argv[0], "info", 4))
|
||||
{
|
||||
if (argc > 2)
|
||||
printf_channel_usage();
|
||||
else
|
||||
{
|
||||
if (argc == 2)
|
||||
ipmi_get_channel_info(intf, (unsigned char)strtol(argv[1], NULL, 0));
|
||||
else
|
||||
ipmi_get_channel_info(intf, 0xe);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Invalid CHANNEL command: %s\n", argv[0]);
|
||||
printf_channel_usage();
|
||||
retval = 1;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
@ -74,7 +74,8 @@ static void ipmi_fru_print(struct ipmi_intf * intf, unsigned char id)
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
unsigned char fru_data[256], msg_data[4];
|
||||
unsigned char * fru_data;
|
||||
unsigned char msg_data[4];
|
||||
int i, len, offset;
|
||||
|
||||
struct fru_area_chassis chassis;
|
||||
@ -101,6 +102,8 @@ static void ipmi_fru_print(struct ipmi_intf * intf, unsigned char id)
|
||||
if (verbose > 1)
|
||||
printf("fru.size = %d bytes (accessed by %s)\n",
|
||||
fru.size, fru.access ? "words" : "bytes");
|
||||
if (!fru.size)
|
||||
return;
|
||||
|
||||
msg_data[0] = id;
|
||||
msg_data[1] = 0;
|
||||
@ -151,8 +154,11 @@ static void ipmi_fru_print(struct ipmi_intf * intf, unsigned char id)
|
||||
printf("fru.header.offset.multi: 0x%x\n", header.offset.multi);
|
||||
}
|
||||
|
||||
fru_data = malloc(fru.size+1);
|
||||
if (!fru_data)
|
||||
return;
|
||||
memset(fru_data, 0, fru.size+1);
|
||||
offset = 0;
|
||||
memset(fru_data, 0, 256);
|
||||
do {
|
||||
msg_data[0] = id;
|
||||
msg_data[1] = offset;
|
||||
@ -391,6 +397,8 @@ static void ipmi_fru_print(struct ipmi_intf * intf, unsigned char id)
|
||||
i += h->len + sizeof (struct fru_multirec_header);
|
||||
} while (!(h->format & 0x80));
|
||||
}
|
||||
|
||||
free(fru_data);
|
||||
}
|
||||
|
||||
static void ipmi_fru_print_all(struct ipmi_intf * intf)
|
||||
|
@ -64,49 +64,6 @@ const struct valstr ipmi_privlvl_vals[] = {
|
||||
{ 0, NULL },
|
||||
};
|
||||
|
||||
const struct valstr ipmi_authtype_vals[] = {
|
||||
{ IPMI_SESSION_AUTHTYPE_NONE, "NONE" },
|
||||
{ IPMI_SESSION_AUTHTYPE_MD2, "MD2" },
|
||||
{ IPMI_SESSION_AUTHTYPE_MD5, "MD5" },
|
||||
{ IPMI_SESSION_AUTHTYPE_KEY, "PASSWORD" },
|
||||
{ IPMI_SESSION_AUTHTYPE_OEM, "OEM" },
|
||||
{ 0, NULL },
|
||||
};
|
||||
|
||||
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 lan_param *
|
||||
get_lan_param(struct ipmi_intf * intf, unsigned char chan, int param)
|
||||
@ -169,131 +126,6 @@ set_lan_param(struct ipmi_intf * intf, unsigned char chan, int param, unsigned c
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
ipmi_get_channel_info(struct ipmi_intf * intf, unsigned char channel)
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
unsigned char rqdata[2];
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.msg.netfn = IPMI_NETFN_APP;
|
||||
req.msg.cmd = 0x42;
|
||||
req.msg.data = &channel;
|
||||
req.msg.data_len = 1;
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
|
||||
if (!rsp || rsp->ccode) {
|
||||
printf("Error:%x Get Channel Info Command (0x%x)\n",
|
||||
rsp ? rsp->ccode : 0, channel);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!verbose)
|
||||
return;
|
||||
|
||||
printf("Channel 0x%x info:\n", rsp->data[0] & 0xf);
|
||||
|
||||
printf(" Channel Medium Type : %s\n",
|
||||
val2str(rsp->data[1] & 0x7f, ipmi_channel_medium_vals));
|
||||
|
||||
printf(" Channel Protocol Type : %s\n",
|
||||
val2str(rsp->data[2] & 0x1f, ipmi_channel_protocol_vals));
|
||||
|
||||
printf(" Session Support : ");
|
||||
switch (rsp->data[3] & 0xc0) {
|
||||
case 0x00:
|
||||
printf("session-less\n");
|
||||
break;
|
||||
case 0x40:
|
||||
printf("single-session\n");
|
||||
break;
|
||||
case 0x80:
|
||||
printf("multi-session\n");
|
||||
break;
|
||||
case 0xc0:
|
||||
default:
|
||||
printf("session-based\n");
|
||||
break;
|
||||
}
|
||||
|
||||
printf(" Active Session Count : %d\n",
|
||||
rsp->data[3] & 0x3f);
|
||||
printf(" Protocol Vendor ID : %d\n",
|
||||
rsp->data[4] | rsp->data[5] << 8 | rsp->data[6] << 16);
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
rqdata[0] = channel & 0xf;
|
||||
|
||||
/* get volatile settings */
|
||||
|
||||
rqdata[1] = 0x80; /* 0x80=active */
|
||||
req.msg.netfn = IPMI_NETFN_APP;
|
||||
req.msg.cmd = 0x41;
|
||||
req.msg.data = rqdata;
|
||||
req.msg.data_len = 2;
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (!rsp || rsp->ccode) {
|
||||
return;
|
||||
}
|
||||
|
||||
printf(" Volatile(active) Settings\n");
|
||||
printf(" Alerting : %sabled\n", (rsp->data[0] & 0x20) ? "dis" : "en");
|
||||
printf(" Per-message Auth : %sabled\n", (rsp->data[0] & 0x10) ? "dis" : "en");
|
||||
printf(" User Level Auth : %sabled\n", (rsp->data[0] & 0x08) ? "dis" : "en");
|
||||
printf(" Access Mode : ");
|
||||
switch (rsp->data[0] & 0x7) {
|
||||
case 0:
|
||||
printf("disabled\n");
|
||||
break;
|
||||
case 1:
|
||||
printf("pre-boot only\n");
|
||||
break;
|
||||
case 2:
|
||||
printf("always available\n");
|
||||
break;
|
||||
case 3:
|
||||
printf("shared\n");
|
||||
break;
|
||||
default:
|
||||
printf("unknown\n");
|
||||
break;
|
||||
}
|
||||
|
||||
/* get non-volatile settings */
|
||||
|
||||
rqdata[1] = 0x40; /* 0x40=non-volatile */
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (!rsp || rsp->ccode) {
|
||||
return;
|
||||
}
|
||||
|
||||
printf(" Non-Volatile Settings\n");
|
||||
printf(" Alerting : %sabled\n", (rsp->data[0] & 0x20) ? "dis" : "en");
|
||||
printf(" Per-message Auth : %sabled\n", (rsp->data[0] & 0x10) ? "dis" : "en");
|
||||
printf(" User Level Auth : %sabled\n", (rsp->data[0] & 0x08) ? "dis" : "en");
|
||||
printf(" Access Mode : ");
|
||||
switch (rsp->data[0] & 0x7) {
|
||||
case 0:
|
||||
printf("disabled\n");
|
||||
break;
|
||||
case 1:
|
||||
printf("pre-boot only\n");
|
||||
break;
|
||||
case 2:
|
||||
printf("always available\n");
|
||||
break;
|
||||
case 3:
|
||||
printf("shared\n");
|
||||
break;
|
||||
default:
|
||||
printf("unknown\n");
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
lan_set_arp_interval(struct ipmi_intf * intf, unsigned char chan, unsigned char * ival)
|
||||
@ -485,7 +317,9 @@ ipmi_lan_set_password(struct ipmi_intf * intf,
|
||||
memset(&data, 0, sizeof(data));
|
||||
data[0] = userid & 0x3f;/* user ID */
|
||||
data[1] = 0x02; /* set password */
|
||||
memcpy(data+2, password, (strlen(password) > 16) ? 16 : strlen(password));
|
||||
|
||||
if (password)
|
||||
memcpy(data+2, password, (strlen(password) > 16) ? 16 : strlen(password));
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.msg.netfn = IPMI_NETFN_APP;
|
||||
@ -506,9 +340,12 @@ ipmi_lan_set_password(struct ipmi_intf * intf,
|
||||
*/
|
||||
lan_session.password = 1;
|
||||
memset(lan_session.authcode, 0, 16);
|
||||
memcpy(lan_session.authcode, password, strlen(password));
|
||||
|
||||
printf("Password for user %d set to %s\n", userid, lan_session.authcode);
|
||||
if (password) {
|
||||
memcpy(lan_session.authcode, password, strlen(password));
|
||||
printf("Password for user %d set to %s\n", userid, lan_session.authcode);
|
||||
}
|
||||
else
|
||||
printf("Password cleared for user %d\n", userid);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -624,7 +461,7 @@ ipmi_lan_set(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
unsigned char chan;
|
||||
memset(&data, 0, sizeof(data));
|
||||
|
||||
if (argc < 2 || !strncmp(argv[0], "help", 4)) {
|
||||
if (argc < 2 || !strncmp(argv[0], "help", 4) || !strncmp(argv[1], "help", 4)) {
|
||||
printf("usage: lan set <channel> <command>\n");
|
||||
printf("LAN set commands: ipaddr, netmask, macaddr, defgw, bakgw, password, auth, ipsrc, access, user, arp\n");
|
||||
return;
|
||||
|
@ -47,6 +47,10 @@
|
||||
#endif
|
||||
|
||||
extern int verbose;
|
||||
static int sdr_max_read_len = GET_SDR_ENTIRE_RECORD;
|
||||
|
||||
static struct sdr_record_list * sdr_list_head = NULL;
|
||||
static struct ipmi_sdr_iterator * sdr_list_itr = NULL;
|
||||
|
||||
/* convert unsigned value to 2's complement signed */
|
||||
int utos(unsigned val, unsigned bits)
|
||||
@ -84,6 +88,29 @@ sdr_convert_sensor_reading(struct sdr_record_full_sensor * sensor, unsigned char
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char
|
||||
sdr_convert_sensor_value_to_raw(struct sdr_record_full_sensor * sensor, float val)
|
||||
{
|
||||
int m, b, k1, k2;
|
||||
double result;
|
||||
|
||||
m = __TO_M(sensor->mtol);
|
||||
b = __TO_B(sensor->bacc);
|
||||
k1 = __TO_B_EXP(sensor->bacc);
|
||||
k2 = __TO_R_EXP(sensor->bacc);
|
||||
|
||||
if (sensor->unit.analog > 2) /* This isn't an analog sensor. */
|
||||
return 0;
|
||||
if (m == 0) /* don't divide by zero */
|
||||
return 0;
|
||||
|
||||
result = ((val / pow(10, k2)) - (b * pow(10, k1))) / m;
|
||||
if ((result -(int)result) >= .5)
|
||||
return (unsigned char)ceil(result);
|
||||
else
|
||||
return (unsigned char)result;
|
||||
}
|
||||
|
||||
#define READING_UNAVAILABLE 0x20
|
||||
#define SCANNING_DISABLED 0x80
|
||||
|
||||
@ -109,7 +136,7 @@ ipmi_sdr_get_sensor_reading(struct ipmi_intf * intf, unsigned char sensor)
|
||||
return rsp;
|
||||
}
|
||||
|
||||
static const char *
|
||||
const char *
|
||||
ipmi_sdr_get_sensor_type_desc(const unsigned char type)
|
||||
{
|
||||
if (type <= SENSOR_TYPE_MAX)
|
||||
@ -161,7 +188,7 @@ ipmi_sdr_get_header(struct ipmi_intf * intf, unsigned short reserve_id, unsigned
|
||||
req.msg.data_len = sizeof(sdr_rq);
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (!rsp || !rsp->data_len) {
|
||||
if (!rsp || !rsp->data_len || rsp->ccode) {
|
||||
printf("Error getting SDR record id 0x%04x\n", record_id);
|
||||
return NULL;
|
||||
}
|
||||
@ -191,7 +218,7 @@ ipmi_sdr_get_next_header(struct ipmi_intf * intf, struct ipmi_sdr_iterator * itr
|
||||
{
|
||||
struct sdr_get_rs *header;
|
||||
|
||||
if (itr->next > itr->total)
|
||||
if (itr->next == 0xffff)
|
||||
return NULL;
|
||||
|
||||
if (!(header = ipmi_sdr_get_header(intf, itr->reservation, itr->next)))
|
||||
@ -211,9 +238,8 @@ static inline int get_offset(unsigned char x)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
ipmi_sdr_print_sensor_full(struct ipmi_intf * intf,
|
||||
struct sdr_record_full_sensor * sensor)
|
||||
void ipmi_sdr_print_sensor_full(struct ipmi_intf * intf,
|
||||
struct sdr_record_full_sensor * sensor)
|
||||
{
|
||||
char sval[16], unitstr[16], desc[17];
|
||||
int i=0, validread=1, do_unit=1;
|
||||
@ -483,9 +509,8 @@ ipmi_sdr_print_sensor_full(struct ipmi_intf * intf,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ipmi_sdr_print_sensor_compact(struct ipmi_intf * intf,
|
||||
struct sdr_record_compact_sensor * sensor)
|
||||
void ipmi_sdr_print_sensor_compact(struct ipmi_intf * intf,
|
||||
struct sdr_record_compact_sensor * sensor)
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
char desc[17];
|
||||
@ -603,9 +628,8 @@ ipmi_sdr_print_sensor_compact(struct ipmi_intf * intf,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ipmi_sdr_print_sensor_eventonly(struct ipmi_intf * intf,
|
||||
struct sdr_record_eventonly_sensor * sensor)
|
||||
void ipmi_sdr_print_sensor_eventonly(struct ipmi_intf * intf,
|
||||
struct sdr_record_eventonly_sensor * sensor)
|
||||
{
|
||||
char desc[17];
|
||||
|
||||
@ -639,9 +663,8 @@ ipmi_sdr_print_sensor_eventonly(struct ipmi_intf * intf,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ipmi_sdr_print_mc_locator(struct ipmi_intf * intf,
|
||||
struct sdr_record_mc_locator * mc)
|
||||
void ipmi_sdr_print_mc_locator(struct ipmi_intf * intf,
|
||||
struct sdr_record_mc_locator * mc)
|
||||
{
|
||||
char desc[17];
|
||||
|
||||
@ -714,9 +737,8 @@ ipmi_sdr_print_mc_locator(struct ipmi_intf * intf,
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static void
|
||||
ipmi_sdr_print_fru_locator(struct ipmi_intf * intf,
|
||||
struct sdr_record_fru_locator * fru)
|
||||
void ipmi_sdr_print_fru_locator(struct ipmi_intf * intf,
|
||||
struct sdr_record_fru_locator * fru)
|
||||
{
|
||||
char desc[17];
|
||||
|
||||
@ -760,8 +782,7 @@ ipmi_sdr_print_fru_locator(struct ipmi_intf * intf,
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void
|
||||
ipmi_sdr_print_sdr(struct ipmi_intf * intf, unsigned char type)
|
||||
void ipmi_sdr_print_sdr(struct ipmi_intf * intf, unsigned char type)
|
||||
{
|
||||
struct sdr_get_rs * header;
|
||||
struct ipmi_sdr_iterator * itr;
|
||||
@ -825,6 +846,29 @@ ipmi_sdr_print_sdr(struct ipmi_intf * intf, unsigned char type)
|
||||
ipmi_sdr_end(intf, itr);
|
||||
}
|
||||
|
||||
int
|
||||
ipmi_sdr_get_reservation (struct ipmi_intf * intf, unsigned short *reserve_id)
|
||||
{
|
||||
struct ipmi_rs *rsp;
|
||||
struct ipmi_rq req;
|
||||
|
||||
/* obtain reservation ID */
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.msg.netfn = IPMI_NETFN_STORAGE;
|
||||
req.msg.cmd = GET_SDR_RESERVE_REPO;
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
|
||||
if (!rsp || !rsp->data_len || rsp->ccode)
|
||||
return 0;
|
||||
|
||||
*reserve_id = ((struct sdr_reserve_repo_rs *) &(rsp->data))->reserve_id;
|
||||
|
||||
if (verbose > 1)
|
||||
printf("SDR reserveration ID %04x\n", *reserve_id);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct ipmi_sdr_iterator *
|
||||
ipmi_sdr_start(struct ipmi_intf * intf)
|
||||
{
|
||||
@ -832,7 +876,6 @@ ipmi_sdr_start(struct ipmi_intf * intf)
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
struct sdr_repo_info_rs sdr_info;
|
||||
struct sdr_reserve_repo_rs sdr_reserve;
|
||||
struct sdr_get_rs * header;
|
||||
|
||||
if (!(itr = malloc (sizeof (struct ipmi_sdr_iterator))))
|
||||
@ -844,7 +887,7 @@ ipmi_sdr_start(struct ipmi_intf * intf)
|
||||
req.msg.cmd = GET_SDR_REPO_INFO;
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (!rsp || !rsp->data_len)
|
||||
if (!rsp || !rsp->data_len || rsp->ccode)
|
||||
{
|
||||
free (itr);
|
||||
return NULL;
|
||||
@ -863,20 +906,11 @@ ipmi_sdr_start(struct ipmi_intf * intf)
|
||||
printf("SDR records: %d\n", sdr_info.count);
|
||||
}
|
||||
|
||||
/* obtain reservation ID */
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.msg.netfn = IPMI_NETFN_STORAGE;
|
||||
req.msg.cmd = GET_SDR_RESERVE_REPO;
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (!rsp || !rsp->data_len)
|
||||
if (!ipmi_sdr_get_reservation (intf, &(itr->reservation)))
|
||||
{
|
||||
free (itr);
|
||||
return NULL;
|
||||
}
|
||||
memcpy(&sdr_reserve, rsp->data, sizeof(sdr_reserve));
|
||||
itr->reservation = sdr_reserve.reserve_id;
|
||||
if (verbose > 1)
|
||||
printf("SDR reserveration ID %04x\n", sdr_reserve.reserve_id);
|
||||
|
||||
itr->next = 0;
|
||||
|
||||
@ -891,10 +925,11 @@ ipmi_sdr_get_record(struct ipmi_intf * intf, struct sdr_get_rs * header,
|
||||
struct ipmi_rs * rsp;
|
||||
struct sdr_get_rq sdr_rq;
|
||||
unsigned char * data;
|
||||
int i, len = header->length;
|
||||
int i = 0, len = header->length;
|
||||
|
||||
if (!(data = malloc(len+1)))
|
||||
return NULL;
|
||||
|
||||
memset(data, 0, len+1);
|
||||
|
||||
memset(&sdr_rq, 0, sizeof(sdr_rq));
|
||||
@ -908,19 +943,51 @@ ipmi_sdr_get_record(struct ipmi_intf * intf, struct sdr_get_rs * header,
|
||||
req.msg.data = (unsigned char *)&sdr_rq;
|
||||
req.msg.data_len = sizeof(sdr_rq);
|
||||
|
||||
/* read SDR record with partial (30 byte) reads
|
||||
* because a full read (0xff) exceeds the maximum
|
||||
/* read SDR record with partial reads
|
||||
* because a full read usually exceeds the maximum
|
||||
* transport buffer size. (completion code 0xca)
|
||||
*/
|
||||
for (i=0; i<len; i+=GET_SDR_MAX_LEN) {
|
||||
sdr_rq.length = (len-i < GET_SDR_MAX_LEN) ? len-i : GET_SDR_MAX_LEN;
|
||||
while (i < len) {
|
||||
sdr_rq.length = (len-i < sdr_max_read_len) ? len-i : sdr_max_read_len;
|
||||
sdr_rq.offset = i+5; /* 5 header bytes */
|
||||
if (verbose > 1)
|
||||
printf("getting %d bytes from SDR at offset %d\n",
|
||||
sdr_rq.length, sdr_rq.offset);
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (rsp && rsp->data)
|
||||
memcpy(data+i, rsp->data+2, sdr_rq.length);
|
||||
|
||||
if (!rsp) {
|
||||
free (data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch (rsp->ccode) {
|
||||
case 0xca:
|
||||
/* read too many bytes at once */
|
||||
sdr_max_read_len = (sdr_max_read_len >> 1) - 1;
|
||||
continue;
|
||||
case 0xc5:
|
||||
/* lost reservation */
|
||||
if (verbose > 1)
|
||||
printf("SDR reserveration canceled. "
|
||||
"Sleeping a bit and retrying...\n");
|
||||
|
||||
sleep (rand () & 3);
|
||||
|
||||
if (!ipmi_sdr_get_reservation (intf, &(itr->reservation))) {
|
||||
free (data);
|
||||
return NULL;
|
||||
}
|
||||
sdr_rq.reserve_id = itr->reservation;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!rsp->data_len || rsp->ccode) {
|
||||
free(data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(data+i, rsp->data+2, sdr_rq.length);
|
||||
i += sdr_max_read_len;
|
||||
}
|
||||
|
||||
return data;
|
||||
@ -932,8 +999,160 @@ ipmi_sdr_end(struct ipmi_intf * intf, struct ipmi_sdr_iterator * itr)
|
||||
free (itr);
|
||||
}
|
||||
|
||||
struct sdr_record_list *
|
||||
ipmi_sdr_find_sdr_byid(struct ipmi_intf * intf, char * id)
|
||||
{
|
||||
struct sdr_get_rs * header;
|
||||
static struct sdr_record_list * sdr_list_tail;
|
||||
static struct sdr_record_list * e;
|
||||
int found = 0;
|
||||
|
||||
if (!sdr_list_itr) {
|
||||
sdr_list_itr = ipmi_sdr_start(intf);
|
||||
if (!sdr_list_itr) {
|
||||
printf("Unable to open SDR for reading\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* check what we've already read */
|
||||
e = sdr_list_head;
|
||||
while (e) {
|
||||
switch (e->type) {
|
||||
case SDR_RECORD_TYPE_FULL_SENSOR:
|
||||
if (!strncmp(e->record.full->id_string, id,
|
||||
e->record.full->id_code & 0x1f))
|
||||
return e;
|
||||
break;
|
||||
case SDR_RECORD_TYPE_COMPACT_SENSOR:
|
||||
if (!strncmp(e->record.compact->id_string, id,
|
||||
e->record.compact->id_code & 0x1f))
|
||||
return e;
|
||||
break;
|
||||
case SDR_RECORD_TYPE_EVENTONLY_SENSOR:
|
||||
if (!strncmp(e->record.eventonly->id_string, id,
|
||||
e->record.eventonly->id_code & 0x1f))
|
||||
return e;
|
||||
break;
|
||||
case SDR_RECORD_TYPE_FRU_DEVICE_LOCATOR:
|
||||
if (!strncmp(e->record.fruloc->id_string, id,
|
||||
e->record.fruloc->id_code & 0x1f))
|
||||
return e;
|
||||
break;
|
||||
case SDR_RECORD_TYPE_MC_DEVICE_LOCATOR:
|
||||
if (!strncmp(e->record.mcloc->id_string, id,
|
||||
e->record.mcloc->id_code & 0x1f))
|
||||
return e;
|
||||
break;
|
||||
}
|
||||
e = e->next;
|
||||
}
|
||||
|
||||
/* now keep looking */
|
||||
while (header = ipmi_sdr_get_next_header(intf, sdr_list_itr)) {
|
||||
unsigned char * rec;
|
||||
struct sdr_record_full_sensor * full;
|
||||
struct sdr_record_compact_sensor * compact;
|
||||
struct sdr_record_list * sdrr;
|
||||
|
||||
sdrr = malloc(sizeof(struct sdr_record_list));
|
||||
memset(sdrr, 0, sizeof(struct sdr_record_list));
|
||||
sdrr->id = header->id;
|
||||
sdrr->type = header->type;
|
||||
|
||||
rec = ipmi_sdr_get_record(intf, header, sdr_list_itr);
|
||||
if (!rec)
|
||||
continue;
|
||||
|
||||
switch (header->type) {
|
||||
case SDR_RECORD_TYPE_FULL_SENSOR:
|
||||
sdrr->record.full = (struct sdr_record_full_sensor *)rec;
|
||||
if (!strncmp(sdrr->record.full->id_string, id,
|
||||
sdrr->record.full->id_code & 0x1f))
|
||||
found = 1;
|
||||
break;
|
||||
case SDR_RECORD_TYPE_COMPACT_SENSOR:
|
||||
sdrr->record.compact = (struct sdr_record_compact_sensor *)rec;
|
||||
if (!strncmp(sdrr->record.compact->id_string, id,
|
||||
sdrr->record.compact->id_code & 0x1f))
|
||||
found = 1;
|
||||
break;
|
||||
case SDR_RECORD_TYPE_EVENTONLY_SENSOR:
|
||||
sdrr->record.eventonly = (struct sdr_record_eventonly_sensor *)rec;
|
||||
if (!strncmp(sdrr->record.eventonly->id_string, id,
|
||||
sdrr->record.eventonly->id_code & 0x1f))
|
||||
found = 1;
|
||||
break;
|
||||
case SDR_RECORD_TYPE_FRU_DEVICE_LOCATOR:
|
||||
sdrr->record.fruloc = (struct sdr_record_fru_locator *)rec;
|
||||
if (!strncmp(sdrr->record.fruloc->id_string, id,
|
||||
sdrr->record.fruloc->id_code & 0x1f))
|
||||
found = 1;
|
||||
break;
|
||||
case SDR_RECORD_TYPE_MC_DEVICE_LOCATOR:
|
||||
sdrr->record.mcloc = (struct sdr_record_mc_locator *)rec;
|
||||
if (!strncmp(sdrr->record.mcloc->id_string, id,
|
||||
sdrr->record.mcloc->id_code & 0x1f))
|
||||
found = 1;
|
||||
break;
|
||||
default:
|
||||
free(rec);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!sdr_list_head)
|
||||
sdr_list_head = sdrr;
|
||||
else
|
||||
sdr_list_tail->next = sdrr;
|
||||
sdr_list_tail = sdrr;
|
||||
|
||||
if (found)
|
||||
return sdrr;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ipmi_sdr_list_empty(struct ipmi_intf * intf)
|
||||
{
|
||||
struct sdr_record_list *list, *next;
|
||||
|
||||
ipmi_sdr_end(intf, sdr_list_itr);
|
||||
|
||||
list = sdr_list_head;
|
||||
while (list) {
|
||||
switch (list->type) {
|
||||
case SDR_RECORD_TYPE_FULL_SENSOR:
|
||||
if (list->record.full)
|
||||
free(list->record.full);
|
||||
break;
|
||||
case SDR_RECORD_TYPE_COMPACT_SENSOR:
|
||||
if (list->record.compact)
|
||||
free(list->record.compact);
|
||||
break;
|
||||
case SDR_RECORD_TYPE_EVENTONLY_SENSOR:
|
||||
if (list->record.eventonly)
|
||||
free(list->record.eventonly);
|
||||
break;
|
||||
case SDR_RECORD_TYPE_FRU_DEVICE_LOCATOR:
|
||||
if (list->record.fruloc)
|
||||
free(list->record.fruloc);
|
||||
break;
|
||||
case SDR_RECORD_TYPE_MC_DEVICE_LOCATOR:
|
||||
if (list->record.mcloc)
|
||||
free(list->record.mcloc);
|
||||
break;
|
||||
}
|
||||
next = list->next;
|
||||
free(list);
|
||||
list = next;
|
||||
}
|
||||
}
|
||||
|
||||
int ipmi_sdr_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
{
|
||||
srand (time (NULL));
|
||||
|
||||
if (!argc)
|
||||
ipmi_sdr_print_sdr(intf, 0xff);
|
||||
else if (!strncmp(argv[0], "help", 4)) {
|
||||
|
@ -36,6 +36,7 @@
|
||||
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <ipmitool/helper.h>
|
||||
#include <ipmitool/ipmi.h>
|
||||
@ -80,6 +81,33 @@ ipmi_get_event_type(unsigned char code)
|
||||
return "Reserved";
|
||||
}
|
||||
|
||||
static char *
|
||||
ipmi_sel_timestamp(uint32_t stamp)
|
||||
{
|
||||
static unsigned char tbuf[40];
|
||||
time_t s = (time_t)stamp;
|
||||
strftime(tbuf, sizeof(tbuf), "%m/%d/%Y %H:%M:%S", localtime(&s));
|
||||
return tbuf;
|
||||
}
|
||||
|
||||
static char *
|
||||
ipmi_sel_timestamp_date(uint32_t stamp)
|
||||
{
|
||||
static unsigned char tbuf[11];
|
||||
time_t s = (time_t)stamp;
|
||||
strftime(tbuf, sizeof(tbuf), "%m/%d/%Y", localtime(&s));
|
||||
return tbuf;
|
||||
}
|
||||
|
||||
static char *
|
||||
ipmi_sel_timestamp_time(uint32_t stamp)
|
||||
{
|
||||
static unsigned char tbuf[9];
|
||||
time_t s = (time_t)stamp;
|
||||
strftime(tbuf, sizeof(tbuf), "%H:%M:%S", localtime(&s));
|
||||
return tbuf;
|
||||
}
|
||||
|
||||
static void
|
||||
ipmi_get_event_desc(struct sel_event_record * rec, char ** desc)
|
||||
{
|
||||
@ -122,7 +150,7 @@ ipmi_sel_get_sensor_type(unsigned char code)
|
||||
return st->type;
|
||||
st++;
|
||||
}
|
||||
return NULL;
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
static void
|
||||
@ -136,7 +164,9 @@ ipmi_sel_get_info(struct ipmi_intf * intf)
|
||||
req.msg.cmd = IPMI_CMD_GET_SEL_INFO;
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (!rsp || rsp->ccode) {
|
||||
if (!rsp)
|
||||
return;
|
||||
if (rsp->ccode) {
|
||||
printf("Error%x in Get SEL Info command\n",
|
||||
rsp ? rsp->ccode : 0);
|
||||
return;
|
||||
@ -145,25 +175,25 @@ ipmi_sel_get_info(struct ipmi_intf * intf)
|
||||
printbuf(rsp->data, rsp->data_len, "sel_info");
|
||||
|
||||
printf("SEL Information\n");
|
||||
printf(" Version : %x%x\n",
|
||||
printf("Version : %x%x\n",
|
||||
(rsp->data[0] & 0xf0) >> 4, rsp->data[0] & 0xf);
|
||||
printf(" Entries : %d\n",
|
||||
printf("Entries : %d\n",
|
||||
buf2short(rsp->data + 1));
|
||||
printf(" Free Space : %d\n",
|
||||
printf("Free Space : %d\n",
|
||||
buf2short(rsp->data + 3));
|
||||
printf(" Last Add Time : %08lx\n",
|
||||
buf2long(rsp->data + 5));
|
||||
printf(" Last Del Time : %08lx\n",
|
||||
buf2long(rsp->data + 9));
|
||||
printf(" Overflow : %s\n",
|
||||
printf("Last Add Time : %s\n",
|
||||
ipmi_sel_timestamp(buf2long(rsp->data + 5)));
|
||||
printf("Last Del Time : %s\n",
|
||||
ipmi_sel_timestamp(buf2long(rsp->data + 9)));
|
||||
printf("Overflow : %s\n",
|
||||
rsp->data[13] & 0x80 ? "true" : "false");
|
||||
printf(" Delete cmd : %ssupported\n",
|
||||
printf("Delete cmd : %ssupported\n",
|
||||
rsp->data[13] & 0x8 ? "" : "un");
|
||||
printf(" Parial add cmd : %ssupported\n",
|
||||
printf("Parial add cmd : %ssupported\n",
|
||||
rsp->data[13] & 0x4 ? "" : "un");
|
||||
printf(" Reserve cmd : %ssupported\n",
|
||||
printf("Reserve cmd : %ssupported\n",
|
||||
rsp->data[13] & 0x2 ? "" : "un");
|
||||
printf(" Get Alloc Info : %ssupported\n",
|
||||
printf("Get Alloc Info : %ssupported\n",
|
||||
rsp->data[13] & 0x1 ? "" : "un");
|
||||
|
||||
if (rsp->data[13] & 0x1) {
|
||||
@ -173,17 +203,19 @@ ipmi_sel_get_info(struct ipmi_intf * intf)
|
||||
req.msg.cmd = IPMI_CMD_GET_SEL_ALLOC_INFO;
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (!rsp || rsp->ccode) {
|
||||
if (!rsp)
|
||||
return;
|
||||
if (rsp->ccode) {
|
||||
printf("error%d in Get SEL Allocation Info command\n",
|
||||
rsp ? rsp->ccode : 0);
|
||||
return;
|
||||
}
|
||||
|
||||
printf(" # of Alloc Units : %d\n", buf2short(rsp->data));
|
||||
printf(" Alloc Unit Size : %d\n", buf2short(rsp->data + 2));
|
||||
printf(" # Free Units : %d\n", buf2short(rsp->data + 4));
|
||||
printf(" Largest Free Blk : %d\n", buf2short(rsp->data + 6));
|
||||
printf(" Max Record Size : %d\n", rsp->data[7]);
|
||||
printf("# of Alloc Units : %d\n", buf2short(rsp->data));
|
||||
printf("Alloc Unit Size : %d\n", buf2short(rsp->data + 2));
|
||||
printf("# Free Units : %d\n", buf2short(rsp->data + 4));
|
||||
printf("Largest Free Blk : %d\n", buf2short(rsp->data + 6));
|
||||
printf("Max Record Size : %d\n", rsp->data[7]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -210,7 +242,9 @@ ipmi_sel_get_std_entry(struct ipmi_intf * intf, unsigned short id, struct sel_ev
|
||||
req.msg.data_len = 6;
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (!rsp || rsp->ccode) {
|
||||
if (!rsp)
|
||||
return 0;
|
||||
if (rsp->ccode) {
|
||||
printf("Error %x in Get SEL Entry %x Command\n",
|
||||
rsp ? rsp->ccode : 0, id);
|
||||
return 0;
|
||||
@ -241,33 +275,6 @@ ipmi_sel_get_std_entry(struct ipmi_intf * intf, unsigned short id, struct sel_ev
|
||||
return (rsp->data[1] << 8) | rsp->data[0];
|
||||
}
|
||||
|
||||
static char *
|
||||
ipmi_sel_timestamp(uint32_t stamp)
|
||||
{
|
||||
static unsigned char tbuf[40];
|
||||
time_t s = (time_t)stamp;
|
||||
strftime(tbuf, sizeof(tbuf), "%m/%d/%Y %H:%M:%S", localtime(&s));
|
||||
return tbuf;
|
||||
}
|
||||
|
||||
static char *
|
||||
ipmi_sel_timestamp_date(uint32_t stamp)
|
||||
{
|
||||
static unsigned char tbuf[11];
|
||||
time_t s = (time_t)stamp;
|
||||
strftime(tbuf, sizeof(tbuf), "%m/%d/%Y", localtime(&s));
|
||||
return tbuf;
|
||||
}
|
||||
|
||||
static char *
|
||||
ipmi_sel_timestamp_time(uint32_t stamp)
|
||||
{
|
||||
static unsigned char tbuf[9];
|
||||
time_t s = (time_t)stamp;
|
||||
strftime(tbuf, sizeof(tbuf), "%H:%M:%S", localtime(&s));
|
||||
return tbuf;
|
||||
}
|
||||
|
||||
void
|
||||
ipmi_sel_print_std_entry(struct sel_event_record * evt)
|
||||
{
|
||||
@ -396,7 +403,7 @@ ipmi_sel_list_entries(struct ipmi_intf * intf)
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
unsigned short reserve_id, next_id = 0;
|
||||
unsigned short next_id = 0;
|
||||
struct sel_event_record evt;
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
@ -404,7 +411,9 @@ ipmi_sel_list_entries(struct ipmi_intf * intf)
|
||||
req.msg.cmd = IPMI_CMD_GET_SEL_INFO;
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (!rsp || rsp->ccode) {
|
||||
if (!rsp)
|
||||
return;
|
||||
if (rsp->ccode) {
|
||||
printf("Error: %x from Get SEL Info command\n",
|
||||
rsp ? rsp->ccode : 0);
|
||||
return;
|
||||
@ -422,23 +431,25 @@ ipmi_sel_list_entries(struct ipmi_intf * intf)
|
||||
req.msg.cmd = IPMI_CMD_RESERVE_SEL;
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (!rsp || rsp->ccode) {
|
||||
if (!rsp)
|
||||
return;
|
||||
if (rsp->ccode) {
|
||||
printf("Error: %x from Reserve SEL command\n",
|
||||
rsp ? rsp->ccode : 0);
|
||||
return;
|
||||
}
|
||||
|
||||
reserve_id = rsp->data[0] | rsp->data[1] << 8;
|
||||
if (verbose)
|
||||
printf("SEL Reservation ID: %04x\n", reserve_id);
|
||||
|
||||
while (next_id != 0xffff) {
|
||||
if (verbose > 1)
|
||||
printf("SEL Next ID: %04x\n", next_id);
|
||||
|
||||
next_id = ipmi_sel_get_std_entry(intf, next_id, &evt);
|
||||
if (!next_id)
|
||||
break;
|
||||
if (!next_id) {
|
||||
/* retry */
|
||||
next_id = ipmi_sel_get_std_entry(intf, next_id, &evt);
|
||||
if (!next_id)
|
||||
break;
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
ipmi_sel_print_std_entry_verbose(&evt);
|
||||
@ -458,7 +469,9 @@ ipmi_sel_reserve(struct ipmi_intf * intf)
|
||||
req.msg.cmd = IPMI_CMD_RESERVE_SEL;
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (!rsp || rsp->ccode) {
|
||||
if (!rsp)
|
||||
return;
|
||||
if (rsp->ccode) {
|
||||
printf("Error:%x unable to reserve SEL\n",
|
||||
rsp ? rsp->ccode : 0);
|
||||
return 0;
|
||||
@ -494,7 +507,9 @@ ipmi_sel_clear(struct ipmi_intf * intf)
|
||||
req.msg.data_len = 6;
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (!rsp || rsp->ccode) {
|
||||
if (!rsp)
|
||||
return;
|
||||
if (rsp->ccode) {
|
||||
printf("Error:%x unable to clear SEL\n", rsp ? rsp->ccode : 0);
|
||||
return;
|
||||
}
|
||||
@ -536,9 +551,12 @@ ipmi_sel_delete(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
req.msg.data_len = 4;
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (!rsp || rsp->ccode)
|
||||
if (!rsp)
|
||||
{
|
||||
printf("No response\n");
|
||||
}
|
||||
else if (rsp->ccode)
|
||||
{
|
||||
if (!rsp) printf("No response\n");
|
||||
printf("Error %x unable to delete entry %d\n", rsp ? rsp->ccode : 0, id);
|
||||
}
|
||||
else
|
||||
|
@ -44,98 +44,699 @@
|
||||
extern int verbose;
|
||||
|
||||
#define READING_UNAVAILABLE 0x20
|
||||
#define SCANNING_DISABLED 0x80
|
||||
|
||||
static void
|
||||
ipmi_get_sensor_info_compact(struct ipmi_intf * intf,
|
||||
struct sdr_record_compact_sensor * sensor)
|
||||
static
|
||||
struct ipmi_rs *
|
||||
ipmi_sensor_get_sensor_thresholds(struct ipmi_intf * intf, unsigned char sensor)
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
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);
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
|
||||
return rsp;
|
||||
}
|
||||
|
||||
static
|
||||
struct ipmi_rs *
|
||||
ipmi_sensor_set_sensor_thresholds(struct ipmi_intf * intf,
|
||||
unsigned char sensor,
|
||||
unsigned char threshold,
|
||||
unsigned char setting)
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
static struct sensor_set_thresh_rq set_thresh_rq;
|
||||
|
||||
memset(&set_thresh_rq, 0, sizeof(set_thresh_rq));
|
||||
set_thresh_rq.sensor_num = sensor;
|
||||
set_thresh_rq.set_mask = threshold;
|
||||
if (threshold == UPPER_NON_RECOV_SPECIFIED)
|
||||
set_thresh_rq.upper_non_recov = setting;
|
||||
else if (threshold == UPPER_CRIT_SPECIFIED)
|
||||
set_thresh_rq.upper_crit = setting;
|
||||
else if (threshold == UPPER_NON_CRIT_SPECIFIED)
|
||||
set_thresh_rq.upper_non_crit = setting;
|
||||
else if (threshold == LOWER_NON_CRIT_SPECIFIED)
|
||||
set_thresh_rq.lower_non_crit = setting;
|
||||
else if (threshold == LOWER_CRIT_SPECIFIED)
|
||||
set_thresh_rq.lower_crit = setting;
|
||||
else if (threshold == LOWER_NON_RECOV_SPECIFIED)
|
||||
set_thresh_rq.lower_non_recov = setting;
|
||||
else
|
||||
return NULL;
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.msg.netfn = IPMI_NETFN_SE;
|
||||
req.msg.cmd = SET_SENSOR_THRESHOLDS;
|
||||
req.msg.data = (unsigned char *)&set_thresh_rq;
|
||||
req.msg.data_len = sizeof(set_thresh_rq);
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
|
||||
return rsp;
|
||||
}
|
||||
|
||||
static void
|
||||
ipmi_get_sensor_info_full(struct ipmi_intf * intf,
|
||||
struct sdr_record_full_sensor * sensor)
|
||||
ipmi_sensor_print_full_discrete(struct ipmi_intf * intf,
|
||||
struct sdr_record_full_sensor * sensor)
|
||||
{
|
||||
char id[17];
|
||||
char * unitstr = "discrete";
|
||||
int i=0, validread=1;
|
||||
unsigned char val;
|
||||
struct ipmi_rs * rsp;
|
||||
char sval[16], unitstr[16], desc[17];
|
||||
float val, tol;
|
||||
unsigned raw_tol;
|
||||
int i=0, not_available=0;
|
||||
char * status;
|
||||
|
||||
memset(desc, 0, sizeof(desc));
|
||||
memcpy(desc, sensor->id_string, 16);
|
||||
if (!sensor)
|
||||
return;
|
||||
|
||||
memset(id, 0, sizeof(id));
|
||||
memcpy(id, sensor->id_string, 16);
|
||||
|
||||
/*
|
||||
* Get current reading
|
||||
*/
|
||||
rsp = ipmi_sdr_get_sensor_reading(intf, sensor->keys.sensor_num);
|
||||
if ((rsp && (rsp->data[1] & READING_UNAVAILABLE)) ||
|
||||
(rsp && !(rsp->data[1] & SCANNING_DISABLED)))
|
||||
not_available = 1;
|
||||
else {
|
||||
memset(unitstr, 0, sizeof(unitstr));
|
||||
/* determine units with possible modifiers */
|
||||
switch (sensor->unit.modifier) {
|
||||
case 2:
|
||||
i += snprintf(unitstr, sizeof(unitstr), "%s * %s",
|
||||
unit_desc[sensor->unit.type.base],
|
||||
unit_desc[sensor->unit.type.modifier]);
|
||||
break;
|
||||
case 1:
|
||||
i += snprintf(unitstr, sizeof(unitstr), "%s/%s",
|
||||
unit_desc[sensor->unit.type.base],
|
||||
unit_desc[sensor->unit.type.modifier]);
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
i += snprintf(unitstr, sizeof(unitstr), "%s",
|
||||
unit_desc[sensor->unit.type.base]);
|
||||
break;
|
||||
}
|
||||
|
||||
val = sdr_convert_sensor_reading(sensor, rsp->data[0]);
|
||||
raw_tol = (sensor->mtol & 0x3f00) >> 8;
|
||||
tol = sdr_convert_sensor_reading(sensor, raw_tol * 2);
|
||||
if (!rsp)
|
||||
{
|
||||
printf("Error reading sensor %s (#%02x)\n", id, sensor->keys.sensor_num);
|
||||
return;
|
||||
}
|
||||
else if (rsp->ccode || (rsp->data[1] & READING_UNAVAILABLE))
|
||||
{
|
||||
validread = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* convert RAW reading into units */
|
||||
val = rsp->data[0];
|
||||
}
|
||||
|
||||
if (!verbose) {
|
||||
/*
|
||||
* print sensor name, reading, state
|
||||
*/
|
||||
printf("%-16s | ", sensor->id_code ? desc : NULL);
|
||||
if (csv_output)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!verbose)
|
||||
{
|
||||
/* output format
|
||||
* id value units status thresholds....
|
||||
*/
|
||||
printf("%-16s ", id);
|
||||
if (validread)
|
||||
{
|
||||
printf("| 0x%-8x | %-10s | 0x%02x%02x",
|
||||
val,
|
||||
unitstr,
|
||||
rsp->data[2],
|
||||
rsp->data[3]);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("| %-10s | %-10s | %-6s",
|
||||
"na",
|
||||
unitstr,
|
||||
"na");
|
||||
}
|
||||
printf("| %-10s| %-10s| %-10s| %-10s| %-10s| %-10s",
|
||||
"na", "na", "na", "na", "na", "na");
|
||||
|
||||
i = 0;
|
||||
memset(sval, 0, sizeof(sval));
|
||||
if (not_available) {
|
||||
i += snprintf(sval, sizeof(sval), "no reading ");
|
||||
} else {
|
||||
i += snprintf(sval, sizeof(sval), "%.*f %s", (val==(int)val) ? 0 : 3, val, unitstr);
|
||||
printf("\n");
|
||||
}
|
||||
printf("%s", sval);
|
||||
|
||||
i--;
|
||||
for (; i<sizeof(sval); i++)
|
||||
printf(" ");
|
||||
printf(" | ");
|
||||
|
||||
printf("%s", ipmi_sdr_get_status(rsp->data[2]));
|
||||
printf("\n");
|
||||
} else {
|
||||
printf("Sensor ID : %s (0x%x)\n", desc, sensor->keys.sensor_num);
|
||||
if (not_available)
|
||||
printf("Sensor Reading : Unavailable");
|
||||
else
|
||||
printf("Sensor Reading : %.*f (+/- %.*f) %s\n",
|
||||
(val==(int)val) ? 0 : 3,
|
||||
val,
|
||||
(tol==(int)tol) ? 0 : 3,
|
||||
tol,
|
||||
unitstr);
|
||||
printf("\n");
|
||||
{
|
||||
printf("Sensor ID : %s (0x%x)\n",
|
||||
id, sensor->keys.sensor_num);
|
||||
|
||||
printf("Sensor Type (Discrete) : %s\n",
|
||||
ipmi_sdr_get_sensor_type_desc(sensor->sensor.type));
|
||||
|
||||
printf("Sensor Reading : ");
|
||||
if (validread)
|
||||
{
|
||||
printf("0x%x\n", val);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("not present\n\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("States Asserted : ");
|
||||
if (!rsp->data[2] && !rsp->data[3])
|
||||
printf("none");
|
||||
else
|
||||
{
|
||||
if (rsp->data[2] & STATE_0_ASSERTED)
|
||||
printf("%d ", 0);
|
||||
if (rsp->data[2] & STATE_1_ASSERTED)
|
||||
printf("%d ", 1);
|
||||
if (rsp->data[2] & STATE_2_ASSERTED)
|
||||
printf("%d ", 2);
|
||||
if (rsp->data[2] & STATE_3_ASSERTED)
|
||||
printf("%d ", 3);
|
||||
if (rsp->data[2] & STATE_4_ASSERTED)
|
||||
printf("%d ", 4);
|
||||
if (rsp->data[2] & STATE_5_ASSERTED)
|
||||
printf("%d ", 5);
|
||||
if (rsp->data[2] & STATE_6_ASSERTED)
|
||||
printf("%d ", 6);
|
||||
if (rsp->data[2] & STATE_7_ASSERTED)
|
||||
printf("%d ", 7);
|
||||
if (rsp->data[3] & STATE_8_ASSERTED)
|
||||
printf("%d ", 8);
|
||||
if (rsp->data[3] & STATE_9_ASSERTED)
|
||||
printf("%d ", 9);
|
||||
if (rsp->data[3] & STATE_10_ASSERTED)
|
||||
printf("%d ", 10);
|
||||
if (rsp->data[3] & STATE_11_ASSERTED)
|
||||
printf("%d ", 11);
|
||||
if (rsp->data[3] & STATE_12_ASSERTED)
|
||||
printf("%d ", 12);
|
||||
if (rsp->data[3] & STATE_13_ASSERTED)
|
||||
printf("%d ", 13);
|
||||
if (rsp->data[3] & STATE_14_ASSERTED)
|
||||
printf("%d ", 14);
|
||||
}
|
||||
|
||||
printf("\n\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ipmi_sensor_print_full_analog(struct ipmi_intf * intf,
|
||||
struct sdr_record_full_sensor * sensor)
|
||||
{
|
||||
char unitstr[16], id[17];
|
||||
int i=0, validread=1, thresh_available = 1;
|
||||
float val;
|
||||
struct ipmi_rs * rsp;
|
||||
char * status;
|
||||
|
||||
if (!sensor)
|
||||
return;
|
||||
|
||||
/* only handle linear sensors (for now) */
|
||||
if (sensor->linearization) {
|
||||
printf("non-linear!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
memset(id, 0, sizeof(id));
|
||||
memcpy(id, sensor->id_string, 16);
|
||||
|
||||
/*
|
||||
* Get current reading
|
||||
*/
|
||||
rsp = ipmi_sdr_get_sensor_reading(intf, sensor->keys.sensor_num);
|
||||
if (!rsp)
|
||||
{
|
||||
printf("Error reading sensor %s (#%02x)\n", id, sensor->keys.sensor_num);
|
||||
return;
|
||||
}
|
||||
else if (rsp->ccode || (rsp->data[1] & READING_UNAVAILABLE))
|
||||
{
|
||||
validread = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* convert RAW reading into units */
|
||||
val = rsp->data[0] ? sdr_convert_sensor_reading(sensor, rsp->data[0]) : 0;
|
||||
status = (char*)ipmi_sdr_get_status(rsp->data[2]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Figure out units
|
||||
*/
|
||||
memset(unitstr, 0, sizeof(unitstr));
|
||||
switch (sensor->unit.modifier)
|
||||
{
|
||||
case 2:
|
||||
i += snprintf(unitstr, sizeof(unitstr), "%s * %s",
|
||||
unit_desc[sensor->unit.type.base],
|
||||
unit_desc[sensor->unit.type.modifier]);
|
||||
break;
|
||||
case 1:
|
||||
i += snprintf(unitstr, sizeof(unitstr), "%s/%s",
|
||||
unit_desc[sensor->unit.type.base],
|
||||
unit_desc[sensor->unit.type.modifier]);
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
i += snprintf(unitstr, sizeof(unitstr), "%s",
|
||||
unit_desc[sensor->unit.type.base]);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get sensor thresholds
|
||||
*/
|
||||
rsp = ipmi_sensor_get_sensor_thresholds(intf, sensor->keys.sensor_num);
|
||||
if (!rsp)
|
||||
thresh_available = 0;
|
||||
|
||||
if (csv_output)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!verbose)
|
||||
{
|
||||
/* output format
|
||||
* id value units status thresholds....
|
||||
*/
|
||||
printf("%-16s ", id);
|
||||
if (validread)
|
||||
{
|
||||
printf("| %-10.3f | %-10s | %-6s",
|
||||
val,
|
||||
unitstr,
|
||||
status);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("| %-10s | %-10s | %-6s",
|
||||
"na",
|
||||
unitstr,
|
||||
"na");
|
||||
}
|
||||
if (thresh_available)
|
||||
{
|
||||
if (rsp->data[0] & LOWER_NON_RECOV_SPECIFIED)
|
||||
printf("| %-10.3f", sdr_convert_sensor_reading(sensor, rsp->data[3]));
|
||||
else
|
||||
printf("| %-10s", "na");
|
||||
if (rsp->data[0] & LOWER_CRIT_SPECIFIED)
|
||||
printf("| %-10.3f", sdr_convert_sensor_reading(sensor, rsp->data[2]));
|
||||
else
|
||||
printf("| %-10s", "na");
|
||||
if (rsp->data[0] & LOWER_NON_CRIT_SPECIFIED)
|
||||
printf("| %-10.3f", sdr_convert_sensor_reading(sensor, rsp->data[1]));
|
||||
else
|
||||
printf("| %-10s", "na");
|
||||
if (rsp->data[0] & UPPER_NON_CRIT_SPECIFIED)
|
||||
printf("| %-10.3f", sdr_convert_sensor_reading(sensor, rsp->data[4]));
|
||||
else
|
||||
printf("| %-10s", "na");
|
||||
if (rsp->data[0] & UPPER_CRIT_SPECIFIED)
|
||||
printf("| %-10.3f", sdr_convert_sensor_reading(sensor, rsp->data[5]));
|
||||
else
|
||||
printf("| %-10s", "na");
|
||||
if (rsp->data[0] & UPPER_NON_RECOV_SPECIFIED)
|
||||
printf("| %-10.3f", sdr_convert_sensor_reading(sensor, rsp->data[6]));
|
||||
else
|
||||
printf("| %-10s", "na");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("| %-10s| %-10s| %-10s| %-10s| %-10s| %-10s",
|
||||
"na", "na", "na", "na", "na", "na");
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Sensor ID : %s (0x%x)\n",
|
||||
id, sensor->keys.sensor_num);
|
||||
|
||||
printf("Sensor Type (Analog) : %s\n",
|
||||
ipmi_sdr_get_sensor_type_desc(sensor->sensor.type));
|
||||
|
||||
printf("Sensor Reading : ");
|
||||
if (validread) {
|
||||
#if WORDS_BIGENDIAN
|
||||
unsigned raw_tol = sensor->mtol & 0x3f;
|
||||
#else
|
||||
unsigned raw_tol = (sensor->mtol & 0x3f00) >> 8;
|
||||
#endif
|
||||
|
||||
float tol = sdr_convert_sensor_reading(sensor, raw_tol * 2);
|
||||
printf("%.*f (+/- %.*f) %s\n",
|
||||
(val==(int)val) ? 0 : 3,
|
||||
val,
|
||||
(tol==(int)tol) ? 0 : 3,
|
||||
tol,
|
||||
unitstr);
|
||||
printf("Status : %s\n", status);
|
||||
|
||||
if (thresh_available)
|
||||
{
|
||||
if (rsp->data[0] & LOWER_NON_RECOV_SPECIFIED)
|
||||
printf("Lower Non-Recoverable : %.3f\n",
|
||||
sdr_convert_sensor_reading(sensor, rsp->data[3]));
|
||||
else
|
||||
printf("Lower Non-Recoverable : na\n");
|
||||
if (rsp->data[0] & LOWER_CRIT_SPECIFIED)
|
||||
printf("Lower Critical : %.3f\n",
|
||||
sdr_convert_sensor_reading(sensor, rsp->data[2]));
|
||||
else
|
||||
printf("Lower Critical : na\n");
|
||||
if (rsp->data[0] & LOWER_NON_CRIT_SPECIFIED)
|
||||
printf("Lower Non-Critical : %.3f\n",
|
||||
sdr_convert_sensor_reading(sensor, rsp->data[1]));
|
||||
else
|
||||
printf("Lower Non-Critical : na\n");
|
||||
if (rsp->data[0] & UPPER_NON_CRIT_SPECIFIED)
|
||||
printf("Upper Non-Critical : %.3f\n",
|
||||
sdr_convert_sensor_reading(sensor, rsp->data[4]));
|
||||
else
|
||||
printf("Upper Non-Critical : na\n");
|
||||
if (rsp->data[0] & UPPER_CRIT_SPECIFIED)
|
||||
printf("Upper Critical : %.3f\n",
|
||||
sdr_convert_sensor_reading(sensor, rsp->data[5]));
|
||||
else
|
||||
printf("Upper Critical : na\n");
|
||||
if (rsp->data[0] & UPPER_NON_RECOV_SPECIFIED)
|
||||
printf("Upper Non-Recoverable : %.3f\n",
|
||||
sdr_convert_sensor_reading(sensor, rsp->data[6]));
|
||||
else
|
||||
printf("Upper Non-Recoverable : na\n");
|
||||
}
|
||||
} else
|
||||
printf("not present\n");
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ipmi_sensor_print_full(struct ipmi_intf * intf,
|
||||
struct sdr_record_full_sensor * sensor)
|
||||
{
|
||||
if (sensor->unit.analog != 3)
|
||||
ipmi_sensor_print_full_analog(intf, sensor);
|
||||
else
|
||||
ipmi_sensor_print_full_discrete(intf, sensor);
|
||||
}
|
||||
|
||||
void ipmi_sensor_print_compact(struct ipmi_intf * intf,
|
||||
struct sdr_record_compact_sensor * sensor)
|
||||
{
|
||||
char id[17];
|
||||
char * unitstr = "discrete";
|
||||
int i=0, validread=1;
|
||||
unsigned char val;
|
||||
struct ipmi_rs * rsp;
|
||||
char * status;
|
||||
|
||||
if (!sensor)
|
||||
return;
|
||||
|
||||
memset(id, 0, sizeof(id));
|
||||
memcpy(id, sensor->id_string, 16);
|
||||
|
||||
/*
|
||||
* Get current reading
|
||||
*/
|
||||
rsp = ipmi_sdr_get_sensor_reading(intf, sensor->keys.sensor_num);
|
||||
if (!rsp)
|
||||
{
|
||||
printf("Error reading sensor %s (#%02x)\n", id, sensor->keys.sensor_num);
|
||||
return;
|
||||
}
|
||||
else if (rsp->ccode || (rsp->data[1] & READING_UNAVAILABLE))
|
||||
{
|
||||
validread = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* convert RAW reading into units */
|
||||
val = rsp->data[0];
|
||||
}
|
||||
|
||||
if (csv_output)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!verbose)
|
||||
{
|
||||
/* output format
|
||||
* id value units status thresholds....
|
||||
*/
|
||||
printf("%-16s ", id);
|
||||
if (validread)
|
||||
{
|
||||
printf("| 0x%-8x | %-10s | 0x%02x%02x",
|
||||
val,
|
||||
unitstr,
|
||||
rsp->data[2],
|
||||
rsp->data[3]);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("| %-10s | %-10s | %-6s",
|
||||
"na",
|
||||
unitstr,
|
||||
"na");
|
||||
}
|
||||
printf("| %-10s| %-10s| %-10s| %-10s| %-10s| %-10s",
|
||||
"na", "na", "na", "na", "na", "na");
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Sensor ID : %s (0x%x)\n",
|
||||
id, sensor->keys.sensor_num);
|
||||
|
||||
printf("Sensor Type (Discrete) : %s\n",
|
||||
ipmi_sdr_get_sensor_type_desc(sensor->sensor.type));
|
||||
|
||||
printf("Sensor Reading : ");
|
||||
if (validread)
|
||||
{
|
||||
printf("0x%04x\n", val);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("not present\n\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("States Asserted : ");
|
||||
if (!rsp->data[2] && !rsp->data[3])
|
||||
printf("none");
|
||||
else
|
||||
{
|
||||
if (rsp->data[2] & STATE_0_ASSERTED)
|
||||
printf("%d ", 0);
|
||||
if (rsp->data[2] & STATE_1_ASSERTED)
|
||||
printf("%d ", 1);
|
||||
if (rsp->data[2] & STATE_2_ASSERTED)
|
||||
printf("%d ", 2);
|
||||
if (rsp->data[2] & STATE_3_ASSERTED)
|
||||
printf("%d ", 3);
|
||||
if (rsp->data[2] & STATE_4_ASSERTED)
|
||||
printf("%d ", 4);
|
||||
if (rsp->data[2] & STATE_5_ASSERTED)
|
||||
printf("%d ", 5);
|
||||
if (rsp->data[2] & STATE_6_ASSERTED)
|
||||
printf("%d ", 6);
|
||||
if (rsp->data[2] & STATE_7_ASSERTED)
|
||||
printf("%d ", 7);
|
||||
if (rsp->data[3] & STATE_8_ASSERTED)
|
||||
printf("%d ", 8);
|
||||
if (rsp->data[3] & STATE_9_ASSERTED)
|
||||
printf("%d ", 9);
|
||||
if (rsp->data[3] & STATE_10_ASSERTED)
|
||||
printf("%d ", 10);
|
||||
if (rsp->data[3] & STATE_11_ASSERTED)
|
||||
printf("%d ", 11);
|
||||
if (rsp->data[3] & STATE_12_ASSERTED)
|
||||
printf("%d ", 12);
|
||||
if (rsp->data[3] & STATE_13_ASSERTED)
|
||||
printf("%d ", 13);
|
||||
if (rsp->data[3] & STATE_14_ASSERTED)
|
||||
printf("%d ", 14);
|
||||
}
|
||||
|
||||
printf("\n\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ipmi_sensor_list(struct ipmi_intf * intf)
|
||||
{
|
||||
ipmi_sdr_print_sdr(intf, 0xff);
|
||||
struct sdr_get_rs * header;
|
||||
struct ipmi_sdr_iterator * itr;
|
||||
|
||||
if (verbose > 1)
|
||||
printf("Querying SDR for sensor list\n");
|
||||
|
||||
itr = ipmi_sdr_start(intf);
|
||||
if (!itr)
|
||||
{
|
||||
printf("Unable to open SDRR for reading\n");
|
||||
return;
|
||||
}
|
||||
|
||||
while (header = ipmi_sdr_get_next_header(intf, itr))
|
||||
{
|
||||
unsigned char * rec = ipmi_sdr_get_record(intf, header, itr);
|
||||
if (!rec)
|
||||
continue;
|
||||
|
||||
switch(header->type)
|
||||
{
|
||||
case SDR_RECORD_TYPE_FULL_SENSOR:
|
||||
ipmi_sensor_print_full(intf, (struct sdr_record_full_sensor *) rec);
|
||||
break;
|
||||
case SDR_RECORD_TYPE_COMPACT_SENSOR:
|
||||
ipmi_sensor_print_compact(intf, (struct sdr_record_compact_sensor *) rec);
|
||||
break;
|
||||
}
|
||||
free(rec);
|
||||
}
|
||||
ipmi_sdr_end(intf, itr);
|
||||
}
|
||||
|
||||
const struct valstr threshold_vals[] = {
|
||||
{ UPPER_NON_RECOV_SPECIFIED, "Upper Non-Recoverable" },
|
||||
{ UPPER_CRIT_SPECIFIED, "Upper Critical" },
|
||||
{ UPPER_NON_CRIT_SPECIFIED, "Upper Non-Critical" },
|
||||
{ LOWER_NON_RECOV_SPECIFIED, "Lower Non-Recoverable" },
|
||||
{ LOWER_CRIT_SPECIFIED, "Lower Critical" },
|
||||
{ LOWER_NON_CRIT_SPECIFIED, "Lower Non-Critical" },
|
||||
{ 0x00, NULL },
|
||||
};
|
||||
|
||||
static void
|
||||
ipmi_sensor_set_threshold(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
{
|
||||
char * id,
|
||||
* thresh;
|
||||
unsigned char settingMask;
|
||||
float setting;
|
||||
struct sdr_record_list * sdr;
|
||||
struct ipmi_rs * rsp;
|
||||
|
||||
if (argc < 3 || !strncmp(argv[0], "help", 4))
|
||||
{
|
||||
printf("sensor thresh <id> <threshold> <setting>\n");
|
||||
printf(" id : name of the sensor for which threshold is to be set\n");
|
||||
printf(" threshold : which threshold to set\n");
|
||||
printf(" unr = upper non-recoverable\n");
|
||||
printf(" ucr = upper critical\n");
|
||||
printf(" unc = upper non-critical\n");
|
||||
printf(" lnc = lower non-critical\n");
|
||||
printf(" lcr = lower critical\n");
|
||||
printf(" lnr = lower non-recoverable\n");
|
||||
printf(" setting : the value to set the threshold to\n");
|
||||
return;
|
||||
}
|
||||
|
||||
id = argv[0];
|
||||
thresh = argv[1];
|
||||
setting = (float)atof(argv[2]);
|
||||
if (!strcmp(thresh, "unr"))
|
||||
{
|
||||
settingMask = UPPER_NON_RECOV_SPECIFIED;
|
||||
}
|
||||
else if (!strcmp(thresh, "ucr"))
|
||||
{
|
||||
settingMask = UPPER_CRIT_SPECIFIED;
|
||||
}
|
||||
else if (!strcmp(thresh, "unc"))
|
||||
{
|
||||
settingMask = UPPER_NON_CRIT_SPECIFIED;
|
||||
}
|
||||
else if (!strcmp(thresh, "lnc"))
|
||||
{
|
||||
settingMask = LOWER_NON_CRIT_SPECIFIED;
|
||||
}
|
||||
else if (!strcmp(thresh, "lcr"))
|
||||
{
|
||||
settingMask = LOWER_CRIT_SPECIFIED;
|
||||
}
|
||||
else if (!strcmp(thresh, "lnr"))
|
||||
{
|
||||
settingMask = LOWER_NON_RECOV_SPECIFIED;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Valid threshold not specified!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Locating sensor record...\n");
|
||||
|
||||
/* lookup by sensor name */
|
||||
sdr = ipmi_sdr_find_sdr_byid(intf, id);
|
||||
if (sdr)
|
||||
{
|
||||
if (sdr->type != SDR_RECORD_TYPE_FULL_SENSOR)
|
||||
{
|
||||
printf("Invalid sensor type %02x\n", sdr->type);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Setting sensor \"%s\" %s threshold to %.3f\n",
|
||||
sdr->record.full->id_string, val2str(settingMask, threshold_vals), setting);
|
||||
rsp = ipmi_sensor_set_sensor_thresholds(intf,
|
||||
sdr->record.full->keys.sensor_num, settingMask,
|
||||
sdr_convert_sensor_value_to_raw(sdr->record.full, setting));
|
||||
if (rsp && rsp->ccode)
|
||||
printf("Error setting threshold: 0x%x\n", rsp->ccode);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Sensor data record not found!\n");
|
||||
}
|
||||
|
||||
ipmi_sdr_list_empty(intf);
|
||||
}
|
||||
|
||||
static void ipmi_sensor_get(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
{
|
||||
struct sdr_record_list * sdr;
|
||||
int i;
|
||||
|
||||
if (argc < 1 || !strncmp(argv[0], "help", 4)) {
|
||||
printf("sensor get <id> ... [id]\n");
|
||||
printf(" id : name of desired sensor\n");
|
||||
return;
|
||||
}
|
||||
printf("Locating sensor record...\n");
|
||||
|
||||
/* lookup by sensor name */
|
||||
for (i=0; i<argc; i++) {
|
||||
sdr = ipmi_sdr_find_sdr_byid(intf, argv[i]);
|
||||
if (sdr) {
|
||||
verbose = verbose ? : 1;
|
||||
switch (sdr->type) {
|
||||
case SDR_RECORD_TYPE_FULL_SENSOR:
|
||||
ipmi_sensor_print_full(intf, sdr->record.full);
|
||||
break;
|
||||
case SDR_RECORD_TYPE_COMPACT_SENSOR:
|
||||
ipmi_sensor_print_compact(intf, sdr->record.compact);
|
||||
break;
|
||||
case SDR_RECORD_TYPE_EVENTONLY_SENSOR:
|
||||
ipmi_sdr_print_sensor_eventonly(intf, sdr->record.eventonly);
|
||||
break;
|
||||
case SDR_RECORD_TYPE_FRU_DEVICE_LOCATOR:
|
||||
ipmi_sdr_print_fru_locator(intf, sdr->record.fruloc);
|
||||
break;
|
||||
case SDR_RECORD_TYPE_MC_DEVICE_LOCATOR:
|
||||
ipmi_sdr_print_mc_locator(intf, sdr->record.mcloc);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
printf("Sensor data record \"%s\" not found!\n", argv[i]);
|
||||
}
|
||||
}
|
||||
|
||||
ipmi_sdr_list_empty(intf);
|
||||
}
|
||||
|
||||
int
|
||||
@ -144,11 +745,17 @@ ipmi_sensor_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
if (!argc)
|
||||
ipmi_sensor_list(intf);
|
||||
else if (!strncmp(argv[0], "help", 4)) {
|
||||
printf("Sensor Commands: list\n");
|
||||
printf("Sensor Commands: list thresh get\n");
|
||||
}
|
||||
else if (!strncmp(argv[0], "list", 4)) {
|
||||
ipmi_sensor_list(intf);
|
||||
}
|
||||
else if (!strncmp(argv[0], "thresh", 5)) {
|
||||
ipmi_sensor_set_threshold(intf, argc-1, &argv[1]);
|
||||
}
|
||||
else if (!strncmp(argv[0], "get", 3)) {
|
||||
ipmi_sensor_get(intf, argc-1, &argv[1]);
|
||||
}
|
||||
else
|
||||
printf("Invalid sensor command: %s\n", argv[0]);
|
||||
return 0;
|
||||
|
@ -37,18 +37,24 @@ SUBDIRS = plugins
|
||||
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
||||
if IPMIEVD
|
||||
EXTRA_DIST = bmcautoconf.sh
|
||||
bin_PROGRAMS = ipmievd ipmitool
|
||||
ipmievd_SOURCES = ipmievd.c
|
||||
ipmievd_LDADD = $(top_srcdir)/lib/libipmitool.la $(top_srcdir)/src/plugins/libintf.la
|
||||
else
|
||||
EXTRA_DIST = bmcautoconf.sh ipmievd.c
|
||||
bin_PROGRAMS = ipmitool
|
||||
endif
|
||||
|
||||
ipmitool_SOURCES = ipmitool.c
|
||||
ipmitool_LDADD = $(top_srcdir)/lib/libipmitool.la $(top_srcdir)/src/plugins/libintf.la
|
||||
LIBIPMITOOL = $(top_srcdir)/lib/libipmitool.la
|
||||
LIBIPMIINTF = $(top_srcdir)/src/plugins/libintf.la
|
||||
|
||||
bin_SCRIPTS = bmcautoconf.sh
|
||||
EXTRA_DIST = bmcautoconf.sh @IPMIEVD_SRC@
|
||||
|
||||
if IPMIADM
|
||||
ipmiadm_SOURCES = ipmitool.c
|
||||
ipmiadm_LDADD = $(LIBIPMITOOL) $(LIBIPMIINTF)
|
||||
else
|
||||
ipmitool_SOURCES = ipmitool.c
|
||||
ipmitool_LDADD = $(LIBIPMITOOL) $(LIBIPMIINTF)
|
||||
endif
|
||||
|
||||
if IPMIEVD
|
||||
ipmievd_SOURCES = ipmievd.c
|
||||
ipmievd_LDADD = $(LIBIPMITOOL) $(LIBIPMIINTF)
|
||||
endif
|
||||
|
||||
bin_PROGRAMS = @IPMITOOL_BIN@ @IPMIEVD_BIN@
|
||||
EXTRA_PROGRAMS = ipmitool ipmiadm ipmievd
|
||||
|
@ -40,7 +40,7 @@
|
||||
#include <sys/ioctl.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/poll.h>
|
||||
|
@ -44,7 +44,6 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <config.h>
|
||||
#include <ipmitool/helper.h>
|
||||
#include <ipmitool/ipmi_intf.h>
|
||||
#include <ipmitool/ipmi.h>
|
||||
@ -56,6 +55,14 @@
|
||||
#include <ipmitool/ipmi_chassis.h>
|
||||
#include <ipmitool/ipmi_bmc.h>
|
||||
#include <ipmitool/ipmi_sensor.h>
|
||||
#include <ipmitool/ipmi_channel.h>
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#else
|
||||
# define IPMITOOL_BIN "ipmitool"
|
||||
#endif
|
||||
|
||||
struct ipmi_session lan_session;
|
||||
int csv_output = 0;
|
||||
@ -63,9 +70,9 @@ int verbose = 0;
|
||||
|
||||
void usage(void)
|
||||
{
|
||||
printf("ipmitool version %s\n", VERSION);
|
||||
printf("%s version %s\n", IPMITOOL_BIN, VERSION);
|
||||
printf("\n");
|
||||
printf("usage: ipmitool [options...] <command>\n");
|
||||
printf("usage: %s [options...] <command>\n", IPMITOOL_BIN);
|
||||
printf("\n");
|
||||
printf(" -h This help\n");
|
||||
printf(" -V Show version information\n");
|
||||
@ -74,11 +81,12 @@ void usage(void)
|
||||
printf(" -g Attempt to be extra robust in LAN communications\n");
|
||||
printf(" -H hostname Remote host name for LAN interface\n");
|
||||
printf(" -p port Remote RMCP port (default is 623)\n");
|
||||
printf(" -P password Remote administrator password\n");
|
||||
printf(" -U username Remote username\n");
|
||||
printf(" -a Prompt for remote password\n");
|
||||
printf(" -E Read remote password from environment variable IPMI_PASSWORD\n");
|
||||
printf(" -P password Remote password\n");
|
||||
printf(" -I intf Inteface to use\n");
|
||||
printf("\n\n");
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
int ipmi_raw_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
@ -108,7 +116,7 @@ int ipmi_raw_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
req.msg.data[i-2] = val;
|
||||
req.msg.data_len++;
|
||||
}
|
||||
if (req.msg.data_len) {
|
||||
if (verbose && req.msg.data_len) {
|
||||
for (i=0; i<req.msg.data_len; i++) {
|
||||
if (((i%16) == 0) && (i != 0))
|
||||
printf("\n");
|
||||
@ -117,8 +125,9 @@ int ipmi_raw_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
printf("RAW REQ (netfn=0x%x cmd=0x%x data_len=%d)\n",
|
||||
req.msg.netfn, req.msg.cmd, req.msg.data_len);
|
||||
if (verbose)
|
||||
printf("RAW REQ (netfn=0x%x cmd=0x%x data_len=%d)\n",
|
||||
req.msg.netfn, req.msg.cmd, req.msg.data_len);
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
|
||||
@ -128,7 +137,8 @@ int ipmi_raw_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("RAW RSP (%d bytes)\n", rsp->data_len);
|
||||
if (verbose)
|
||||
printf("RAW RSP (%d bytes)\n", rsp->data_len);
|
||||
|
||||
for (i=0; i<rsp->data_len; i++) {
|
||||
if (((i%16) == 0) && (i != 0))
|
||||
@ -253,22 +263,22 @@ int main(int argc, char ** argv)
|
||||
{
|
||||
int (*submain)(struct ipmi_intf *, int, char **);
|
||||
struct ipmi_intf * intf = NULL;
|
||||
char * hostname = NULL, * password = NULL, * username = NULL;
|
||||
int argflag, i, rc=0, port = 623, pedantic = 0;
|
||||
char * hostname = NULL, * password = NULL, * username = NULL, * tmp;
|
||||
int argflag, i, intfarg = 0, rc = 0, port = 623, pedantic = 0;
|
||||
char intfname[32];
|
||||
|
||||
if (ipmi_intf_init() < 0)
|
||||
exit(EXIT_FAILURE);
|
||||
memset(intfname, 0, sizeof(intfname));
|
||||
|
||||
while ((argflag = getopt(argc, (char **)argv, "hVvcgI:H:P:U:p:")) != -1)
|
||||
while ((argflag = getopt(argc, (char **)argv, "hVvcgEaI:H:P:U:p:")) != -1)
|
||||
{
|
||||
switch (argflag) {
|
||||
case 'h':
|
||||
usage();
|
||||
goto out_free;
|
||||
break;
|
||||
case 'V':
|
||||
printf("ipmitool version %s\n", VERSION);
|
||||
exit(EXIT_SUCCESS);
|
||||
printf("%s version %s\n", IPMITOOL_BIN, VERSION);
|
||||
goto out_free;
|
||||
break;
|
||||
case 'g':
|
||||
pedantic = 1;
|
||||
@ -280,20 +290,54 @@ int main(int argc, char ** argv)
|
||||
csv_output = 1;
|
||||
break;
|
||||
case 'I':
|
||||
memset(intfname, 0, sizeof(intfname));
|
||||
i = snprintf(intfname, sizeof(intfname), "intf_%s", optarg);
|
||||
intf = ipmi_intf_load(intfname);
|
||||
if (!intf) {
|
||||
printf("Error loading interface %s\n", optarg);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
intfarg = snprintf(intfname, sizeof(intfname), "intf_%s", optarg);
|
||||
break;
|
||||
case 'H':
|
||||
hostname = strdup(optarg);
|
||||
break;
|
||||
case 'P':
|
||||
if (password)
|
||||
free (password);
|
||||
|
||||
password = strdup(optarg);
|
||||
|
||||
/* Prevent password snooping with ps */
|
||||
i = strlen (optarg);
|
||||
memset (optarg, 'X', i);
|
||||
|
||||
break;
|
||||
|
||||
case 'E':
|
||||
if ((tmp = getenv ("IPMITOOL_PASSWORD")))
|
||||
{
|
||||
if (password)
|
||||
free (password);
|
||||
|
||||
password = strdup (tmp);
|
||||
}
|
||||
else if ((tmp = getenv("IPMI_PASSWORD")))
|
||||
{
|
||||
if (password)
|
||||
free (password);
|
||||
|
||||
password = strdup (tmp);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
#ifdef HAVE_GETPASSPHRASE
|
||||
if ((tmp = getpassphrase ("Password: ")))
|
||||
#else
|
||||
if ((tmp = getpass ("Password: ")))
|
||||
#endif
|
||||
{
|
||||
if (password)
|
||||
free (password);
|
||||
|
||||
password = strdup (tmp);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'U':
|
||||
username = strdup(optarg);
|
||||
break;
|
||||
@ -302,23 +346,33 @@ int main(int argc, char ** argv)
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
goto out_free;
|
||||
}
|
||||
}
|
||||
|
||||
if (argc-optind <= 0) {
|
||||
printf("No command provided!\n");
|
||||
usage();
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
if (!intf) {
|
||||
if (intfarg) {
|
||||
intf = ipmi_intf_load(intfname);
|
||||
if (!intf) {
|
||||
printf("Error loading interface %s\n", optarg);
|
||||
goto out_free;
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("No interface specified!\n");
|
||||
usage();
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
intf->pedantic = pedantic;
|
||||
|
||||
if (!strncmp(argv[optind], "help", 4)) {
|
||||
printf("Commands: bmc, chaninfo, chassis, event, fru, lan, raw, sdr, sel, sensor, sol, userinfo\n");
|
||||
printf("Commands: bmc, chassis, event, fru, lan, raw, sdr, sel, sensor, sol, userinfo, channel\n");
|
||||
goto out_free;
|
||||
}
|
||||
else if (!strncmp(argv[optind], "event", 5)) {
|
||||
@ -374,21 +428,8 @@ int main(int argc, char ** argv)
|
||||
goto out_free;
|
||||
}
|
||||
}
|
||||
else if (!strncmp(argv[optind], "chaninfo", 8)) {
|
||||
if (argc-optind-1 > 0) {
|
||||
unsigned char c = (unsigned char)strtol(argv[optind+1], NULL, 0);
|
||||
rc = intf->open(intf, hostname, port, username, password);
|
||||
if (rc < 0)
|
||||
goto out_free;
|
||||
verbose++;
|
||||
ipmi_get_channel_info(intf, c);
|
||||
verbose--;
|
||||
goto out_close;
|
||||
}
|
||||
else {
|
||||
printf("chaninfo <channel>\n");
|
||||
goto out_free;
|
||||
}
|
||||
else if (!strncmp(argv[optind], "channel", 7)) {
|
||||
submain = ipmi_channel_main;
|
||||
}
|
||||
else {
|
||||
printf("Invalid comand: %s\n", argv[optind]);
|
||||
@ -411,9 +452,9 @@ int main(int argc, char ** argv)
|
||||
if (intf->close)
|
||||
intf->close(intf);
|
||||
|
||||
out_free:
|
||||
ipmi_intf_exit();
|
||||
|
||||
out_free:
|
||||
if (hostname)
|
||||
free(hostname);
|
||||
if (username)
|
||||
|
@ -50,13 +50,14 @@ extern struct static_intf static_intf_list[];
|
||||
int ipmi_intf_init(void)
|
||||
{
|
||||
if (lt_dlinit() < 0) {
|
||||
printf("ERROR: Unable to initialize ltdl\n");
|
||||
printf("ERROR: Unable to initialize ltdl: %s\n",
|
||||
lt_dlerror());
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (lt_dlsetsearchpath(PLUGIN_PATH) < 0) {
|
||||
printf("ERROR: Unable to set ltdl plugin path to %s\n",
|
||||
PLUGIN_PATH);
|
||||
printf("ERROR: Unable to set ltdl plugin path to %s: %s\n",
|
||||
PLUGIN_PATH, lt_dlerror());
|
||||
lt_dlexit();
|
||||
return -1;
|
||||
}
|
||||
@ -70,7 +71,8 @@ int ipmi_intf_init(void)
|
||||
void ipmi_intf_exit(void)
|
||||
{
|
||||
if (lt_dlexit() < 0)
|
||||
printf("ERROR: Unable to cleanly exit ltdl\n");
|
||||
printf("ERROR: Unable to cleanly exit ltdl: %s\n",
|
||||
lt_dlerror());
|
||||
}
|
||||
|
||||
/* ipmi_intf_load
|
||||
@ -95,6 +97,9 @@ struct ipmi_intf * ipmi_intf_load(char * name)
|
||||
i++;
|
||||
}
|
||||
|
||||
if (ipmi_intf_init() < 0)
|
||||
return NULL;
|
||||
|
||||
memset(libname, 0, 16);
|
||||
if (snprintf(libname, sizeof(libname), "lib%s", name) <= 0) {
|
||||
printf("ERROR: Unable to find plugin '%s' in '%s'\n",
|
||||
@ -104,14 +109,16 @@ struct ipmi_intf * ipmi_intf_load(char * name)
|
||||
|
||||
handle = lt_dlopenext(libname);
|
||||
if (handle == NULL) {
|
||||
printf("ERROR: Unable to find plugin '%s' in '%s'\n",
|
||||
libname, PLUGIN_PATH);
|
||||
printf("ERROR: Unable to find plugin '%s' in '%s': %s\n",
|
||||
libname, PLUGIN_PATH, lt_dlerror());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
setup = lt_dlsym(handle, "intf_setup");
|
||||
if (!setup) {
|
||||
printf("ERROR: Unable to find interface setup symbol in plugin %s\n", name);
|
||||
printf("ERROR: Unable to find interface setup symbol "
|
||||
"in plugin %s: %s\n", name,
|
||||
lt_dlerror());
|
||||
lt_dlclose(handle);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -36,7 +36,7 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
@ -50,7 +50,12 @@
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <ipmitool/helper.h>
|
||||
#include <ipmitool/bswap.h>
|
||||
#include <ipmitool/ipmi.h>
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "lan.h"
|
||||
#include "md5.h"
|
||||
@ -60,10 +65,18 @@
|
||||
struct ipmi_rq_entry * ipmi_req_entries;
|
||||
static struct ipmi_rq_entry * ipmi_req_entries_tail;
|
||||
|
||||
extern int h_errno;
|
||||
int verbose;
|
||||
|
||||
static int recv_timeout = 1;
|
||||
const struct valstr ipmi_authtype_session_vals[] = {
|
||||
{ IPMI_SESSION_AUTHTYPE_NONE, "NONE" },
|
||||
{ IPMI_SESSION_AUTHTYPE_MD2, "MD2" },
|
||||
{ IPMI_SESSION_AUTHTYPE_MD5, "MD5" },
|
||||
{ IPMI_SESSION_AUTHTYPE_PASSWORD, "PASSWORD" },
|
||||
{ IPMI_SESSION_AUTHTYPE_OEM, "OEM" },
|
||||
{ 0, NULL },
|
||||
};
|
||||
|
||||
static int recv_timeout = IPMI_LAN_TIMEOUT;
|
||||
static int curr_seq;
|
||||
static sigjmp_buf jmpbuf;
|
||||
struct ipmi_session lan_session;
|
||||
@ -158,6 +171,8 @@ ipmi_req_remove_entry(unsigned char seq, unsigned char cmd)
|
||||
else
|
||||
ipmi_req_entries_tail = NULL;
|
||||
}
|
||||
if (e->msg_data)
|
||||
free(e->msg_data);
|
||||
free(e);
|
||||
}
|
||||
}
|
||||
@ -195,15 +210,10 @@ get_random(void *data, unsigned int len)
|
||||
|
||||
int ipmi_lan_send_packet(struct ipmi_intf * intf, unsigned char * data, int data_len)
|
||||
{
|
||||
socklen_t addrlen;
|
||||
|
||||
if (verbose > 2)
|
||||
printbuf(data, data_len, "send_packet");
|
||||
|
||||
addrlen = sizeof(intf->addr);
|
||||
|
||||
return send(intf->fd, data, data_len, 0);
|
||||
// (struct sockaddr *)&intf->addr, addrlen);
|
||||
}
|
||||
|
||||
struct ipmi_rs * ipmi_lan_recv_packet(struct ipmi_intf * intf)
|
||||
@ -392,13 +402,23 @@ unsigned char * ipmi_auth_md5(unsigned char * data, int data_len)
|
||||
{
|
||||
md5_state_t state;
|
||||
static md5_byte_t digest[16];
|
||||
uint32_t temp;
|
||||
|
||||
memset(digest, 0, 16);
|
||||
memset(&state, 0, sizeof(md5_state_t));
|
||||
|
||||
md5_init(&state);
|
||||
|
||||
md5_append(&state, (const md5_byte_t *)lan_session.authcode, 16);
|
||||
md5_append(&state, (const md5_byte_t *)&lan_session.id, 4);
|
||||
md5_append(&state, (const md5_byte_t *)data, data_len);
|
||||
md5_append(&state, (const md5_byte_t *)&lan_session.in_seq, 4);
|
||||
|
||||
#if WORDS_BIGENDIAN
|
||||
temp = BSWAP_32(lan_session.in_seq);
|
||||
#else
|
||||
temp = lan_session.in_seq;
|
||||
#endif
|
||||
md5_append(&state, (const md5_byte_t *)&temp, 4);
|
||||
md5_append(&state, (const md5_byte_t *)lan_session.authcode, 16);
|
||||
|
||||
md5_finish(&state, digest);
|
||||
@ -468,7 +488,7 @@ ipmi_lan_poll_recv(struct ipmi_intf * intf)
|
||||
printbuf(rsp->data, x, "ipmi message header");
|
||||
printf("<< IPMI Response Session Header\n");
|
||||
printf("<< Authtype : %s\n",
|
||||
val2str(rsp->session.authtype, ipmi_authtype_vals));
|
||||
val2str(rsp->session.authtype, ipmi_authtype_session_vals));
|
||||
printf("<< Sequence : 0x%08lx\n", rsp->session.seq);
|
||||
printf("<< Session ID : 0x%08lx\n", rsp->session.id);
|
||||
|
||||
@ -614,7 +634,8 @@ ipmi_lan_build_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
|
||||
|
||||
if (verbose > 2) {
|
||||
printf(">> IPMI Request Session Header\n");
|
||||
printf(">> Authtype : %s\n", val2str(lan_session.authtype, ipmi_authtype_vals));
|
||||
printf(">> Authtype : %s\n",
|
||||
val2str(lan_session.authtype, ipmi_authtype_session_vals));
|
||||
printf(">> Sequence : 0x%08lx\n", lan_session.in_seq);
|
||||
printf(">> Session ID : 0x%08lx\n", lan_session.id);
|
||||
|
||||
@ -661,6 +682,7 @@ ipmi_lan_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
|
||||
{
|
||||
struct ipmi_rq_entry * entry;
|
||||
struct ipmi_rs * rsp;
|
||||
int try = 0;
|
||||
|
||||
entry = ipmi_lan_build_cmd(intf, req);
|
||||
if (!entry) {
|
||||
@ -668,35 +690,24 @@ ipmi_lan_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ipmi_lan_send_packet(intf, entry->msg_data, entry->msg_len) < 0) {
|
||||
printf("ipmi_lan_send_cmd failed\n");
|
||||
free(entry->msg_data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (intf->pedantic)
|
||||
ipmi_lan_pedantic(intf);
|
||||
|
||||
rsp = ipmi_lan_poll_recv(intf);
|
||||
if (!rsp) {
|
||||
while (try < IPMI_LAN_RETRY) {
|
||||
if (ipmi_lan_send_packet(intf, entry->msg_data, entry->msg_len) < 0) {
|
||||
printf("ipmi_lan_send_cmd failed\n");
|
||||
free(entry->msg_data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (intf->pedantic)
|
||||
ipmi_lan_pedantic(intf);
|
||||
|
||||
rsp = ipmi_lan_poll_recv(intf);
|
||||
if (!rsp) {
|
||||
free(entry->msg_data);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
usleep(100);
|
||||
|
||||
free(entry->msg_data);
|
||||
entry->msg_len = 0;
|
||||
rsp = ipmi_lan_poll_recv(intf);
|
||||
if (rsp)
|
||||
break;
|
||||
|
||||
usleep(5000);
|
||||
try++;
|
||||
}
|
||||
|
||||
return rsp;
|
||||
}
|
||||
@ -746,8 +757,8 @@ ipmi_get_auth_capabilities_cmd(struct ipmi_intf * intf)
|
||||
printf("MD2 ");
|
||||
if (rsp->data[1] & 1<<IPMI_SESSION_AUTHTYPE_MD5)
|
||||
printf("MD5 ");
|
||||
if (rsp->data[1] & 1<<IPMI_SESSION_AUTHTYPE_KEY)
|
||||
printf("KEY ");
|
||||
if (rsp->data[1] & 1<<IPMI_SESSION_AUTHTYPE_PASSWORD)
|
||||
printf("PASSWORD ");
|
||||
if (rsp->data[1] & 1<<IPMI_SESSION_AUTHTYPE_OEM)
|
||||
printf("OEM ");
|
||||
printf("\n");
|
||||
@ -769,8 +780,8 @@ ipmi_get_auth_capabilities_cmd(struct ipmi_intf * intf)
|
||||
lan_session.authtype = IPMI_SESSION_AUTHTYPE_MD5;
|
||||
}
|
||||
else if (lan_session.password &&
|
||||
rsp->data[1] & 1<<IPMI_SESSION_AUTHTYPE_KEY) {
|
||||
lan_session.authtype = IPMI_SESSION_AUTHTYPE_KEY;
|
||||
rsp->data[1] & 1<<IPMI_SESSION_AUTHTYPE_PASSWORD) {
|
||||
lan_session.authtype = IPMI_SESSION_AUTHTYPE_PASSWORD;
|
||||
}
|
||||
else if (rsp->data[1] & 1<<IPMI_SESSION_AUTHTYPE_NONE) {
|
||||
lan_session.authtype = IPMI_SESSION_AUTHTYPE_NONE;
|
||||
@ -782,7 +793,7 @@ ipmi_get_auth_capabilities_cmd(struct ipmi_intf * intf)
|
||||
|
||||
if (verbose > 1)
|
||||
printf("Proceeding with AuthType %s\n",
|
||||
val2str(lan_session.authtype, ipmi_authtype_vals));
|
||||
val2str(lan_session.authtype, ipmi_authtype_session_vals));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -820,10 +831,10 @@ ipmi_get_session_challenge_cmd(struct ipmi_intf * intf)
|
||||
printf("Get Session Challenge error: ");
|
||||
switch (rsp->ccode) {
|
||||
case 0x81:
|
||||
printf("invalid user name\n");
|
||||
printf("Invalid user name\n");
|
||||
break;
|
||||
case 0x82:
|
||||
printf("null user name not enabled\n");
|
||||
printf("NULL user name not enabled\n");
|
||||
break;
|
||||
default:
|
||||
printf("%02x\n", rsp->ccode);
|
||||
@ -876,15 +887,12 @@ ipmi_activate_session_cmd(struct ipmi_intf * intf)
|
||||
printf(" Privilege Level : %s\n",
|
||||
val2str(msg_data[1], ipmi_privlvl_vals));
|
||||
printf(" Auth Type : %s\n",
|
||||
val2str(lan_session.authtype, ipmi_authtype_vals));
|
||||
if (lan_session.authtype)
|
||||
printf(" AuthCode : %s\n",
|
||||
lan_session.authcode);
|
||||
val2str(lan_session.authtype, ipmi_authtype_session_vals));
|
||||
}
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
if (!rsp) {
|
||||
printf("error in Activate Session Command\n");
|
||||
printf("Error in Activate Session Command\n");
|
||||
lan_session.active = 0;
|
||||
return -1;
|
||||
}
|
||||
@ -895,24 +903,27 @@ ipmi_activate_session_cmd(struct ipmi_intf * intf)
|
||||
printf("Activate Session error: ");
|
||||
switch (rsp->ccode) {
|
||||
case 0x81:
|
||||
printf("no session slot available\n");
|
||||
printf("No session slot available\n");
|
||||
break;
|
||||
case 0x82:
|
||||
printf("no slot available for given user - "
|
||||
printf("No slot available for given user - "
|
||||
"limit reached\n");
|
||||
break;
|
||||
case 0x83:
|
||||
printf("no slot available to support user "
|
||||
printf("No slot available to support user "
|
||||
"due to maximum privilege capacity\n");
|
||||
break;
|
||||
case 0x84:
|
||||
printf("session sequence number out of range\n");
|
||||
printf("Session sequence number out of range\n");
|
||||
break;
|
||||
case 0x85:
|
||||
printf("invalid session ID in request\n");
|
||||
printf("Invalid session ID in request\n");
|
||||
break;
|
||||
case 0x86:
|
||||
printf("requested privilege level exceeds limit\n");
|
||||
printf("Requested privilege level exceeds limit\n");
|
||||
break;
|
||||
case 0xd4:
|
||||
printf("Insufficient privilege level\n");
|
||||
break;
|
||||
default:
|
||||
printf("%02x\n", rsp->ccode);
|
||||
@ -926,7 +937,7 @@ ipmi_activate_session_cmd(struct ipmi_intf * intf)
|
||||
if (verbose > 1) {
|
||||
printf("\nSession Activated\n");
|
||||
printf(" Auth Type : %s\n",
|
||||
val2str(rsp->data[0], ipmi_authtype_vals));
|
||||
val2str(rsp->data[0], ipmi_authtype_session_vals));
|
||||
printf(" Max Priv Level : %s\n",
|
||||
val2str(rsp->data[9], ipmi_privlvl_vals));
|
||||
printf(" Session ID : %08lx\n", lan_session.id);
|
||||
@ -1049,27 +1060,31 @@ ipmi_lan_activate_session(struct ipmi_intf * intf)
|
||||
|
||||
rc = ipmi_get_auth_capabilities_cmd(intf);
|
||||
if (rc < 0) {
|
||||
sleep(1);
|
||||
rc = ipmi_get_auth_capabilities_cmd(intf);
|
||||
if (rc < 0)
|
||||
return -1;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rc = ipmi_get_session_challenge_cmd(intf);
|
||||
if (rc < 0)
|
||||
return -1;
|
||||
goto fail;
|
||||
|
||||
rc = ipmi_activate_session_cmd(intf);
|
||||
if (rc < 0)
|
||||
return -1;
|
||||
goto fail;
|
||||
|
||||
rc = ipmi_set_session_privlvl_cmd(intf);
|
||||
if (rc < 0)
|
||||
return -1;
|
||||
goto fail;
|
||||
|
||||
/* channel 0xE will query current channel */
|
||||
// ipmi_get_channel_info(intf, IPMI_LAN_CHANNEL_E);
|
||||
intf->abort = 0;
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
printf("Error: Unable to establish LAN session\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
void ipmi_lan_close(struct ipmi_intf * intf)
|
||||
@ -1108,7 +1123,7 @@ int ipmi_lan_open(struct ipmi_intf * intf, char * hostname, int port, char * use
|
||||
memcpy(lan_session.authcode, password, strlen(password));
|
||||
}
|
||||
|
||||
intf->abort = 0;
|
||||
intf->abort = 1;
|
||||
|
||||
/* open port to BMC */
|
||||
memset(&intf->addr, 0, sizeof(struct sockaddr_in));
|
||||
|
@ -43,10 +43,13 @@
|
||||
#define IPMI_LAN_CHANNEL_2 0x06
|
||||
#define IPMI_LAN_CHANNEL_E 0x0e
|
||||
|
||||
#define IPMI_LAN_TIMEOUT 2
|
||||
#define IPMI_LAN_RETRY 4
|
||||
|
||||
#define IPMI_SESSION_AUTHTYPE_NONE 0x0
|
||||
#define IPMI_SESSION_AUTHTYPE_MD2 0x1
|
||||
#define IPMI_SESSION_AUTHTYPE_MD5 0x2
|
||||
#define IPMI_SESSION_AUTHTYPE_KEY 0x4
|
||||
#define IPMI_SESSION_AUTHTYPE_PASSWORD 0x4
|
||||
#define IPMI_SESSION_AUTHTYPE_OEM 0x5
|
||||
|
||||
#define IPMI_SESSION_PRIV_CALLBACK 0x1
|
||||
|
Reference in New Issue
Block a user