summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile73
-rw-r--r--lib/ipmilib.mak37
-rw-r--r--lib/lanplus/Makefile.am55
-rw-r--r--lib/lanplus/Makefile.in532
-rw-r--r--lib/lanplus/README19
-rw-r--r--lib/lanplus/asf.h82
-rw-r--r--lib/lanplus/helper.c480
-rw-r--r--lib/lanplus/inc/config.h144
-rw-r--r--lib/lanplus/inc/inttypes-win.h30
-rw-r--r--lib/lanplus/inc/ipmitool/bswap.h53
-rw-r--r--lib/lanplus/inc/ipmitool/helper.h102
-rw-r--r--lib/lanplus/inc/ipmitool/ipmi.h267
-rw-r--r--lib/lanplus/inc/ipmitool/ipmi_cc.h76
-rw-r--r--lib/lanplus/inc/ipmitool/ipmi_channel.h229
-rw-r--r--lib/lanplus/inc/ipmitool/ipmi_chassis.h55
-rw-r--r--lib/lanplus/inc/ipmitool/ipmi_constants.h136
-rw-r--r--lib/lanplus/inc/ipmitool/ipmi_entity.h47
-rw-r--r--lib/lanplus/inc/ipmitool/ipmi_event.h60
-rw-r--r--lib/lanplus/inc/ipmitool/ipmi_firewall.h106
-rw-r--r--lib/lanplus/inc/ipmitool/ipmi_fru.h381
-rw-r--r--lib/lanplus/inc/ipmitool/ipmi_fwum.h46
-rw-r--r--lib/lanplus/inc/ipmitool/ipmi_hpmfwupg.h45
-rw-r--r--lib/lanplus/inc/ipmitool/ipmi_intf.h224
-rw-r--r--lib/lanplus/inc/ipmitool/ipmi_isol.h56
-rw-r--r--lib/lanplus/inc/ipmitool/ipmi_kontronoem.h49
-rw-r--r--lib/lanplus/inc/ipmitool/ipmi_lanp.h132
-rw-r--r--lib/lanplus/inc/ipmitool/ipmi_main.h42
-rw-r--r--lib/lanplus/inc/ipmitool/ipmi_mc.h103
-rw-r--r--lib/lanplus/inc/ipmitool/ipmi_oem.h47
-rw-r--r--lib/lanplus/inc/ipmitool/ipmi_pef.h784
-rw-r--r--lib/lanplus/inc/ipmitool/ipmi_picmg.h90
-rw-r--r--lib/lanplus/inc/ipmitool/ipmi_raw.h44
-rw-r--r--lib/lanplus/inc/ipmitool/ipmi_sdr.h876
-rw-r--r--lib/lanplus/inc/ipmitool/ipmi_sel.h542
-rw-r--r--lib/lanplus/inc/ipmitool/ipmi_sensor.h84
-rw-r--r--lib/lanplus/inc/ipmitool/ipmi_session.h125
-rw-r--r--lib/lanplus/inc/ipmitool/ipmi_sol.h84
-rw-r--r--lib/lanplus/inc/ipmitool/ipmi_strings.h60
-rw-r--r--lib/lanplus/inc/ipmitool/ipmi_sunoem.h57
-rw-r--r--lib/lanplus/inc/ipmitool/ipmi_tsol.h46
-rw-r--r--lib/lanplus/inc/ipmitool/ipmi_user.h89
-rw-r--r--lib/lanplus/inc/ipmitool/log.h74
-rw-r--r--lib/lanplus/ipmi_strings.c348
-rw-r--r--lib/lanplus/ipmiplus.mak67
-rw-r--r--lib/lanplus/lanplus.c4036
-rw-r--r--lib/lanplus/lanplus.h135
-rw-r--r--lib/lanplus/lanplus_crypt.c1038
-rw-r--r--lib/lanplus/lanplus_crypt.h79
-rw-r--r--lib/lanplus/lanplus_crypt_impl.c320
-rw-r--r--lib/lanplus/lanplus_crypt_impl.h66
-rw-r--r--lib/lanplus/lanplus_defs.h376
-rw-r--r--lib/lanplus/lanplus_dump.c174
-rw-r--r--lib/lanplus/lanplus_dump.h45
-rw-r--r--lib/lanplus/lanplus_strings.c45
-rw-r--r--lib/lanplus/libipmi_lanplus.la35
-rw-r--r--lib/lanplus/rmcp.h88
-rw-r--r--lib/libimbapi64.a.redhatbin0 -> 47244 bytes
-rw-r--r--lib/libimbapi64.a.susebin0 -> 11644 bytes
58 files changed, 13515 insertions, 0 deletions
diff --git a/lib/Makefile b/lib/Makefile
new file mode 100644
index 0000000..c5c9030
--- /dev/null
+++ b/lib/Makefile
@@ -0,0 +1,73 @@
+#!/bin/sh
+# Makefile to build/install ipmiutil lib files
+#
+# If --enable-lanplus (-DHAVE_LANPLUS), then this script
+# does a make from lib/lanplus/ for the lanplus library.
+# If --enable-landesk (-DLINK_LANDESK), then this script
+# assumes that these files are copied into this lib/ directory:
+# libipmiapi32.a libipmiapi64.a.suse libipmiapi64.a.redhat
+#
+MKDIR = sh ../mkinstalldirs
+INSTALL = sh ../install-sh -c
+INSTALL_DATA = $(INSTALL) -m 644
+INSTALL_SCRIPT = $(INSTALL) -m 755
+INSTALL_BIN = /usr/bin/install -c
+prefix = /usr
+
+datadir = ${prefix}/share
+mandir = ${prefix}/man
+sbindir = ${exec_prefix}/sbin
+libdir = ${exec_prefix}/lib
+datato = ${DESTDIR}${datadir}/ipmiutil
+lib32 = ${DESTDIR}/usr/lib
+lib64 = ${DESTDIR}/usr/lib64
+
+all:
+ if [ -f libipmiapi32.a ]; then \
+ rm -f libipmiapi.a; \
+ if [ "`uname -m`" = "x86_64" ]; then \
+ if [ -f /etc/SuSE-release ]; then \
+ cp -f libipmiapi64.a.suse libipmiapi.a; \
+ else cp -f libipmiapi64.a.redhat libipmiapi.a; fi \
+ else cp -f libipmiapi32.a libipmiapi.a; fi \
+ fi
+ cd lanplus; make clean; make
+ cp -f lanplus/libipmi_lanplus.a .
+ # cp -f lanplus/.libs/libipmi_lanplus.so.0.0.0 libipmi_lanplus.so
+
+clean:
+ rm -f libipmiapi.a lib*_lanplus.a lib*_lanplus.so
+ cd lanplus; make clean
+
+clobber:
+ rm -f libipmiapi.a lib*_lanplus.a lib*_lanplus.so
+ cd lanplus; make clean
+
+distclean:
+ rm -f libipmiapi.a lib*.a lib*_lanplus.so
+ cd lanplus; make distclean
+
+install:
+ $(MKDIR) ${datato}
+ cd lanplus; make install
+
+check:
+
+installso:
+ @if [ -d /usr/lib64 ]; then \
+ $(MKDIR) ${lib64} ; \
+ echo "installing libipmi_lanplus into ${lib64}"; \
+ cd lanplus; /bin/sh ../../libtool --mode=install $(INSTALL_BIN) 'libipmi_lanplus.la' '${lib64}/libipmi_lanplus.la' ; \
+ $(INSTALL_BIN) .libs/libipmi_lanplus.so.0.0.0 ${lib64}/libipmi_lanplus.so.0.0.0 ; \
+ (cd ${lib64} && rm -f libipmi_lanplus.so.0 && ln -s libipmi_lanplus.so.0.0.0 libipmi_lanplus.so.0) ; \
+ (cd ${lib64} && rm -f libipmi_lanplus.so && ln -s libipmi_lanplus.so.0.0.0 libipmi_lanplus.so) ; \
+ $(INSTALL_BIN) .libs/libipmi_lanplus.lai ${lib64}/libipmi_lanplus.la ; \
+ $(INSTALL_BIN) .libs/libipmi_lanplus.a ${lib64}/libipmi_lanplus.a; \
+ ranlib ${lib64}/libipmi_lanplus.a ; \
+ chmod 644 ${lib64}/libipmi_lanplus.a ; \
+ (cd ${lib32} && rm -f libipmi_lanplus.* ); \
+ ../../libtool --finish ${lib64} \
+ fi
+
+# $(INSTALL_DATA) libipmiapi.a ${datato}
+# $(INSTALL_DATA) libintf_lanplus.a ${datato}
diff --git a/lib/ipmilib.mak b/lib/ipmilib.mak
new file mode 100644
index 0000000..a894d3f
--- /dev/null
+++ b/lib/ipmilib.mak
@@ -0,0 +1,37 @@
+# ipmilib.mak
+# This makefile will build the ipmiutil lib directory
+#
+# Make sure to download and build openssl for Windows
+#
+
+# The ipmiutil lib directory
+PLUS_DIR=lanplus
+PLUS_LIB=lanplus.lib
+
+# Set your compiler options
+RM=del
+CP=copy
+
+all: banner $(PLUS_LIB)
+
+banner:
+ @echo Building ipmi libs
+
+$(PLUS_LIB):
+ cd $(PLUS_DIR)
+ nmake /nologo -f ipmiplus.mak all
+ cd ..
+ $(CP) $(PLUS_DIR)\$(PLUS_LIB) .
+
+clean:
+ $(RM) $(PLUS_LIB) 2>NUL
+ cd $(PLUS_DIR)
+ nmake /nologo -f ipmiplus.mak clean
+ cd ..
+
+distclean:
+ $(RM) $(PLUS_LIB) 2>NUL
+ cd $(PLUS_DIR)
+ nmake /nologo -f ipmiplus.mak distclean
+ cd ..
+
diff --git a/lib/lanplus/Makefile.am b/lib/lanplus/Makefile.am
new file mode 100644
index 0000000..c5394b1
--- /dev/null
+++ b/lib/lanplus/Makefile.am
@@ -0,0 +1,55 @@
+# Makefile.am for libipmi_lanplus.so and libipmi_lanplus.a
+
+ODIR = obj
+CFLAGS_STATIC = @OS_CFLAGS@ -DSTATIC -fno-strict-aliasing -fPIC $(CFLAGS)
+AM_CFLAGS = @OS_CFLAGS@ -fPIC @LANPLUS_CFLAGS@
+
+MAINTAINERCLEANFILES = Makefile.in
+
+INCLUDES = -I. -I./inc
+
+lanplus_liba = libipmi_lanplus.a
+
+noinst_LIBRARIES = $(lanplus_liba)
+
+libipmi_lanplus_a_SOURCES = lanplus.c lanplus.h rmcp.h asf.h \
+ lanplus_dump.c lanplus_dump.h \
+ lanplus_crypt.c lanplus_crypt.h \
+ lanplus_crypt_impl.c lanplus_crypt_impl.h \
+ lanplus_strings.c \
+ helper.c ipmi_strings.c
+
+lib_LTLIBRARIES =
+# lib_LTLIBRARIES = libipmi_lanplus.la
+
+# libipmi_lanplus_la_LIBADD = -lcrypto
+
+# libipmi_lanplus_la_SOURCES = lanplus.c lanplus.h rmcp.h asf.h \
+# lanplus_dump.c lanplus_dump.h \
+# lanplus_crypt.c lanplus_crypt.h \
+# lanplus_crypt_impl.c lanplus_crypt_impl.h \
+# lanplus_strings.c \
+# helper.c ipmi_strings.c
+
+
+#am_libipmi_lanplus_a_OBJECTS = $(ODIR)/lanplus.o $(ODIR)/lanplus_strings.o \
+# $(ODIR)/lanplus_crypt.o $(ODIR)/lanplus_crypt_impl.o \
+# $(ODIR)/lanplus_dump.o \
+# $(ODIR)/helper.o $(ODIR)/ipmi_strings.o
+
+clean-generic:
+ rm -rf $(ODIR)
+ rm -f $(lanplus_liba) $(lib_LTLIBRARIES) *.o *.so
+
+clean: clean-generic
+
+#$(lanplus_liba): $(am_libipmi_lanplus_a_OBJECTS)
+# $(AR) cru $(lanplus_liba) $(am_libipmi_lanplus_a_OBJECTS)
+# $(RANLIB) $(lanplus_liba)
+
+#$(ODIR):
+# mkdir -p $(ODIR)
+
+#$(ODIR)/%.o: %.c $(ODIR)
+# $(CC) -c $(CFLAGS_STATIC) $(INCLUDES) -o $@ $<
+
diff --git a/lib/lanplus/Makefile.in b/lib/lanplus/Makefile.in
new file mode 100644
index 0000000..91f0bd7
--- /dev/null
+++ b/lib/lanplus/Makefile.in
@@ -0,0 +1,532 @@
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Makefile.am for libipmi_lanplus.so and libipmi_lanplus.a
+
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ../..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = lib/lanplus
+DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+LIBRARIES = $(noinst_LIBRARIES)
+ARFLAGS = cru
+libipmi_lanplus_a_AR = $(AR) $(ARFLAGS)
+libipmi_lanplus_a_LIBADD =
+am_libipmi_lanplus_a_OBJECTS = lanplus.$(OBJEXT) \
+ lanplus_dump.$(OBJEXT) lanplus_crypt.$(OBJEXT) \
+ lanplus_crypt_impl.$(OBJEXT) lanplus_strings.$(OBJEXT) \
+ helper.$(OBJEXT) ipmi_strings.$(OBJEXT)
+libipmi_lanplus_a_OBJECTS = $(am_libipmi_lanplus_a_OBJECTS)
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(libdir)"
+libLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(lib_LTLIBRARIES)
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(libipmi_lanplus_a_SOURCES)
+DIST_SOURCES = $(libipmi_lanplus_a_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CROSS_CFLAGS = @CROSS_CFLAGS@
+CROSS_LFLAGS = @CROSS_LFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GPL_CFLAGS = @GPL_CFLAGS@
+IA64_CFLAGS = @IA64_CFLAGS@
+INIT_DIR = @INIT_DIR@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INS_LIB = @INS_LIB@
+LANDESK_CFLAGS = @LANDESK_CFLAGS@
+LANDESK_LDADD = @LANDESK_LDADD@
+LANPLUS_CFLAGS = @LANPLUS_CFLAGS@
+LANPLUS_CRYPTO = @LANPLUS_CRYPTO@
+LANPLUS_LDADD = @LANPLUS_LDADD@
+LANPLUS_LIB = @LANPLUS_LIB@
+LANPLUS_SAM = @LANPLUS_SAM@
+LDFLAGS = @LDFLAGS@
+LD_SAMX = @LD_SAMX@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIB_DIR = @LIB_DIR@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+OBJEXT = @OBJEXT@
+OS_CFLAGS = @OS_CFLAGS@
+OS_DRIVERS = @OS_DRIVERS@
+OS_LFLAGS = @OS_LFLAGS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_DIR = @PKG_DIR@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SHR_LINK = @SHR_LINK@
+STRIP = @STRIP@
+SUBDIR_S = @SUBDIR_S@
+SYSTEMD_DIR = @SYSTEMD_DIR@
+VERSION = @VERSION@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
+am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+ODIR = obj
+CFLAGS_STATIC = @OS_CFLAGS@ -DSTATIC -fno-strict-aliasing -fPIC $(CFLAGS)
+AM_CFLAGS = @OS_CFLAGS@ -fPIC @LANPLUS_CFLAGS@
+MAINTAINERCLEANFILES = Makefile.in
+INCLUDES = -I. -I./inc
+lanplus_liba = libipmi_lanplus.a
+noinst_LIBRARIES = $(lanplus_liba)
+libipmi_lanplus_a_SOURCES = lanplus.c lanplus.h rmcp.h asf.h \
+ lanplus_dump.c lanplus_dump.h \
+ lanplus_crypt.c lanplus_crypt.h \
+ lanplus_crypt_impl.c lanplus_crypt_impl.h \
+ lanplus_strings.c \
+ helper.c ipmi_strings.c
+
+lib_LTLIBRARIES =
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/lanplus/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --foreign lib/lanplus/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+clean-noinstLIBRARIES:
+ -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+libipmi_lanplus.a: $(libipmi_lanplus_a_OBJECTS) $(libipmi_lanplus_a_DEPENDENCIES)
+ -rm -f libipmi_lanplus.a
+ $(libipmi_lanplus_a_AR) libipmi_lanplus.a $(libipmi_lanplus_a_OBJECTS) $(libipmi_lanplus_a_LIBADD)
+ $(RANLIB) libipmi_lanplus.a
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)"
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ f=$(am__strip_dir) \
+ echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
+ $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @set -x; list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \
+ $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \
+ done
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/helper.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipmi_strings.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lanplus.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lanplus_crypt.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lanplus_crypt_impl.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lanplus_dump.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lanplus_strings.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+ -rm -f libtool
+uninstall-info-am:
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+ list='$(DISTFILES)'; for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+ esac; \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkdir_p) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
+ if test -d $$d/$$file; then \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LIBRARIES) $(LTLIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(libdir)"; do \
+ test -z "$$dir" || $(mkdir_p) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
+ clean-noinstLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-libtool distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am: install-libLTLIBRARIES
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-info-am uninstall-libLTLIBRARIES
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libLTLIBRARIES clean-libtool clean-noinstLIBRARIES ctags \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-exec install-exec-am install-info \
+ install-info-am install-libLTLIBRARIES install-man \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags uninstall uninstall-am \
+ uninstall-info-am uninstall-libLTLIBRARIES
+
+# lib_LTLIBRARIES = libipmi_lanplus.la
+
+# libipmi_lanplus_la_LIBADD = -lcrypto
+
+# libipmi_lanplus_la_SOURCES = lanplus.c lanplus.h rmcp.h asf.h \
+# lanplus_dump.c lanplus_dump.h \
+# lanplus_crypt.c lanplus_crypt.h \
+# lanplus_crypt_impl.c lanplus_crypt_impl.h \
+# lanplus_strings.c \
+# helper.c ipmi_strings.c
+
+#am_libipmi_lanplus_a_OBJECTS = $(ODIR)/lanplus.o $(ODIR)/lanplus_strings.o \
+# $(ODIR)/lanplus_crypt.o $(ODIR)/lanplus_crypt_impl.o \
+# $(ODIR)/lanplus_dump.o \
+# $(ODIR)/helper.o $(ODIR)/ipmi_strings.o
+
+clean-generic:
+ rm -rf $(ODIR)
+ rm -f $(lanplus_liba) $(lib_LTLIBRARIES) *.o *.so
+
+clean: clean-generic
+
+#$(lanplus_liba): $(am_libipmi_lanplus_a_OBJECTS)
+# $(AR) cru $(lanplus_liba) $(am_libipmi_lanplus_a_OBJECTS)
+# $(RANLIB) $(lanplus_liba)
+
+#$(ODIR):
+# mkdir -p $(ODIR)
+
+#$(ODIR)/%.o: %.c $(ODIR)
+# $(CC) -c $(CFLAGS_STATIC) $(INCLUDES) -o $@ $<
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/lib/lanplus/README b/lib/lanplus/README
new file mode 100644
index 0000000..8a155e6
--- /dev/null
+++ b/lib/lanplus/README
@@ -0,0 +1,19 @@
+ipmitool/plugins/lanplus for ipmiutil
+
+lib/lanplus directory
+
+This contains the lanplus plugin source from the ipmitool project,
+which supports IPMI LAN 2.0 RMCP+ protocol.
+This is a slightly modified version from ipmitool-1.8.8.90 with changes
+to link better with ipmiutil and changes for WIN32.
+
+See http://ipmitool.sourceforge.net for the latest version of lanplus,
+then apply the iutil.diff patch to make it compatible with ipmiutil.
+
+This builds a lanplus library that is used by ipmiutil, along with
+the crypto libraries from openssl (see openssl.org).
+
+The util/ipmilanplus.c code in ipmiutil calls the lanplus routines,
+if the HAVE_LANPLUS compile flag is defined.
+
+
diff --git a/lib/lanplus/asf.h b/lib/lanplus/asf.h
new file mode 100644
index 0000000..acf5553
--- /dev/null
+++ b/lib/lanplus/asf.h
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ */
+
+#ifndef IPMI_ASF_H
+#define IPMI_ASF_H
+
+#include <ipmitool/helper.h>
+#include "lanplus.h"
+
+#define ASF_RMCP_IANA 0x000011be
+
+#define ASF_TYPE_PING 0x80
+#define ASF_TYPE_PONG 0x40
+
+static const struct valstr asf_type_vals[] __attribute__((unused)) = {
+ { 0x10, "Reset" },
+ { 0x11, "Power-up" },
+ { 0x12, "Unconditional Power-down" },
+ { 0x13, "Power Cycle" },
+ { 0x40, "Presence Pong" },
+ { 0x41, "Capabilities Response" },
+ { 0x42, "System State Response" },
+ { 0x80, "Presence Ping" },
+ { 0x81, "Capabilities Request" },
+ { 0x82, "System State Request" },
+ { 0x00, NULL }
+};
+
+/* ASF message header */
+#ifdef GCC_42
+struct asf_hdr {
+ uint32_t iana;
+ uint8_t type;
+ uint8_t tag;
+ uint8_t reserved;
+ uint8_t len;
+} __attribute__((packed));
+#else
+/* pragma pack works in gcc-4.3 */
+#pragma pack(1)
+struct asf_hdr {
+ uint32_t iana;
+ uint8_t type;
+ uint8_t tag;
+ uint8_t reserved;
+ uint8_t len;
+};
+#pragma pack()
+#endif
+
+int handle_asf(struct ipmi_intf * intf, uint8_t * data, int data_len);
+
+#endif /* IPMI_ASF_H */
diff --git a/lib/lanplus/helper.c b/lib/lanplus/helper.c
new file mode 100644
index 0000000..51e39c8
--- /dev/null
+++ b/lib/lanplus/helper.c
@@ -0,0 +1,480 @@
+/*
+ * 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.
+ */
+
+#ifdef WIN32
+#include <windows.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <io.h>
+#include <signal.h>
+#include <inttypes-win.h>
+#else
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h> /* For TIOCNOTTY */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <inttypes.h>
+#include <signal.h>
+#include <string.h>
+#include <strings.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#endif
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef HAVE_PATHS_H
+#include <paths.h>
+#else
+#define _PATH_VARRUN "/var/run/"
+#define _PATH_TTY "/dev/tty"
+#endif
+
+#include <ipmitool/ipmi.h>
+#include <ipmitool/ipmi_intf.h>
+#include <ipmitool/helper.h>
+#include <ipmitool/log.h>
+
+extern int verbose;
+
+#ifdef MOVED
+/* moved to subs.c */
+uint32_t buf2long(uint8_t * buf)
+{
+ return (uint32_t)(buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0]);
+}
+
+uint16_t buf2short(uint8_t * buf)
+{
+ return (uint16_t)(buf[1] << 8 | buf[0]);
+}
+
+const char * buf2str(uint8_t * buf, int len)
+{
+ static char str[1024];
+ int i;
+
+ if (len <= 0 || len > 1024)
+ return NULL;
+
+ memset(str, 0, 1024);
+
+ for (i=0; i<len; i++)
+ sprintf(str+i+i, "%2.2x", buf[i]);
+
+ str[len*2] = '\0';
+
+ return (const char *)str;
+}
+
+/* moved to util/ipmilanplus.c for better control */
+#ifdef STATIC
+extern FILE *fplog; /*see util/ipmicmd.c ++++*/
+#endif
+void printbuf(const uint8_t * buf, int len, const char * desc)
+{
+ int i;
+ FILE *fp = stderr;
+
+ if (len <= 0) return;
+ if (verbose < 1) return;
+#ifdef STATIC
+ if (fplog != NULL) fp = fplog; /*++++*/
+#endif
+ fprintf(fp, "%s (%d bytes)\r\n", desc, len);
+ for (i=0; i<len; i++) {
+ if (((i%16) == 0) && (i != 0))
+ fprintf(fp, "\r\n");
+ fprintf(fp, " %2.2x", buf[i]);
+ }
+ fprintf(fp, "\r\n");
+}
+
+const char * val2str(uint16_t val, const struct valstr *vs)
+{
+ static char un_str[32];
+ int i;
+
+ for (i = 0; vs[i].str != NULL; i++) {
+ if (vs[i].val == val)
+ return vs[i].str;
+ }
+
+ memset(un_str, 0, 32);
+ snprintf(un_str, 32, "Unknown (0x%x)", val);
+
+ return un_str;
+}
+
+const char * oemval2str(uint16_t oem, uint16_t val,
+ const struct oemvalstr *vs)
+{
+ static char un_str[32];
+ int i;
+
+ for (i = 0; vs[i].oem != 0x00 && vs[i].str != NULL; i++) {
+ /* FIXME: for now on we assume PICMG capability on all IANAs */
+ if
+ (
+ (
+ vs[i].oem == oem
+ ||
+ vs[i].oem == IPMI_OEM_PICMG
+ )
+ &&
+ vs[i].val == val
+ )
+ {
+ return vs[i].str;
+ }
+ }
+
+ memset(un_str, 0, 32);
+ snprintf(un_str, 32, "OEM reserved #%02x", val);
+
+ return un_str;
+}
+
+uint16_t str2val(const char *str, const struct valstr *vs)
+{
+ int i;
+
+ for (i = 0; vs[i].str != NULL; i++) {
+ if (strcasecmp(vs[i].str, str) == 0)
+ return vs[i].val;
+ }
+
+ return vs[i].val;
+}
+#else
+uint32_t buf2long(uint8_t * buf);
+uint16_t buf2short(uint8_t * buf);
+const char * buf2str(uint8_t * buf, int len);
+void printbuf(const uint8_t * buf, int len, const char * desc);
+const char * val2str(uint16_t val, const struct valstr *vs);
+const char * oemval2str(uint16_t oem, uint16_t val,
+ const struct oemvalstr *vs);
+uint16_t str2val(const char *str, const struct valstr *vs);
+#endif
+
+/* print_valstr - print value string list to log or stdout
+ *
+ * @vs: value string list to print
+ * @title: name of this value string list
+ * @loglevel: what log level to print, -1 for stdout
+ */
+void
+print_valstr(const struct valstr * vs, const char * title, int loglevel)
+{
+ int i;
+
+ if (vs == NULL)
+ return;
+
+ if (title != NULL) {
+ if (loglevel < 0)
+ printf("\n%s:\n\n", title);
+ else
+ lprintf(loglevel, "\n%s:\n", title);
+ }
+
+ if (loglevel < 0) {
+ printf(" VALUE\tHEX\tSTRING\n");
+ printf("==============================================\n");
+ } else {
+ lprintf(loglevel, " VAL\tHEX\tSTRING");
+ lprintf(loglevel, "==============================================");
+ }
+
+ for (i = 0; vs[i].str != NULL; i++) {
+ if (loglevel < 0) {
+ if (vs[i].val < 256)
+ printf(" %d\t0x%02x\t%s\n", vs[i].val, vs[i].val, vs[i].str);
+ else
+ printf(" %d\t0x%04x\t%s\n", vs[i].val, vs[i].val, vs[i].str);
+ } else {
+ if (vs[i].val < 256)
+ lprintf(loglevel, " %d\t0x%02x\t%s", vs[i].val, vs[i].val, vs[i].str);
+ else
+ lprintf(loglevel, " %d\t0x%04x\t%s", vs[i].val, vs[i].val, vs[i].str);
+ }
+ }
+
+ if (loglevel < 0)
+ printf("\n");
+ else
+ lprintf(loglevel, "");
+}
+
+/* print_valstr_2col - print value string list in two columns to log or stdout
+ *
+ * @vs: value string list to print
+ * @title: name of this value string list
+ * @loglevel: what log level to print, -1 for stdout
+ */
+void
+print_valstr_2col(const struct valstr * vs, const char * title, int loglevel)
+{
+ int i;
+
+ if (vs == NULL)
+ return;
+
+ if (title != NULL) {
+ if (loglevel < 0)
+ printf("\n%s:\n\n", title);
+ else
+ lprintf(loglevel, "\n%s:\n", title);
+ }
+
+ for (i = 0; vs[i].str != NULL; i++) {
+ if (vs[i+1].str == NULL) {
+ /* last one */
+ if (loglevel < 0) {
+ printf(" %4d %-32s\n", vs[i].val, vs[i].str);
+ } else {
+ lprintf(loglevel, " %4d %-32s\n", vs[i].val, vs[i].str);
+ }
+ }
+ else {
+ if (loglevel < 0) {
+ printf(" %4d %-32s %4d %-32s\n",
+ vs[i].val, vs[i].str, vs[i+1].val, vs[i+1].str);
+ } else {
+ lprintf(loglevel, " %4d %-32s %4d %-32s\n",
+ vs[i].val, vs[i].str, vs[i+1].val, vs[i+1].str);
+ }
+ i++;
+ }
+ }
+
+ if (loglevel < 0)
+ printf("\n");
+ else
+ lprintf(loglevel, "");
+}
+
+/* ipmi_csum - calculate an ipmi checksum
+ *
+ * @d: buffer to check
+ * @s: position in buffer to start checksum from
+ */
+uint8_t
+ipmi_csum(uint8_t * d, int s)
+{
+ uint8_t c = 0;
+ for (; s > 0; s--, d++)
+ c += *d;
+ return -c;
+}
+
+/* ipmi_open_file - safely open a file for reading or writing
+ *
+ * @file: filename
+ * @rw: read-write flag, 1=write
+ *
+ * returns pointer to file handler on success
+ * returns NULL on error
+ */
+FILE *
+ipmi_open_file(const char * file, int rw)
+{
+#ifndef WIN32
+ struct stat st1, st2;
+#endif
+ FILE * fp;
+
+ /* verify existence */
+#ifdef WIN32
+ if (1 == 0)
+#else
+ if (lstat(file, &st1) < 0)
+#endif
+ {
+ if (rw) {
+ /* does not exist, ok to create */
+ fp = fopen(file, "w");
+ if (fp == NULL) {
+ lperror(LOG_ERR, "Unable to open file %s "
+ "for write", file);
+ return NULL;
+ }
+ /* created ok, now return the descriptor */
+ return fp;
+ } else {
+ lprintf(LOG_ERR, "File %s does not exist", file);
+ return NULL;
+ }
+ }
+
+#ifndef ENABLE_FILE_SECURITY
+ if (!rw) {
+ /* on read skip the extra checks */
+ fp = fopen(file, "r");
+ if (fp == NULL) {
+ lperror(LOG_ERR, "Unable to open file %s", file);
+ return NULL;
+ }
+ return fp;
+ }
+#endif
+
+#ifndef WIN32
+ /* it exists - only regular files, not links */
+ if (S_ISREG(st1.st_mode) == 0) {
+ lprintf(LOG_ERR, "File %s has invalid mode: %d",
+ file, st1.st_mode);
+ return NULL;
+ }
+
+ /* allow only files with 1 link (itself) */
+ if (st1.st_nlink != 1) {
+ lprintf(LOG_ERR, "File %s has invalid link count: %d != 1",
+ file, (int)st1.st_nlink);
+ return NULL;
+ }
+#endif
+
+ fp = fopen(file, rw ? "w+" : "r");
+ if (fp == NULL) {
+ lperror(LOG_ERR, "Unable to open file %s", file);
+ return NULL;
+ }
+
+#ifndef WIN32
+ /* stat again */
+ if (fstat(fileno(fp), &st2) < 0) {
+ lperror(LOG_ERR, "Unable to stat file %s", file);
+ fclose(fp);
+ return NULL;
+ }
+
+ /* verify inode */
+ if (st1.st_ino != st2.st_ino) {
+ lprintf(LOG_ERR, "File %s has invalid inode: %d != %d",
+ file, st1.st_ino, st2.st_ino);
+ fclose(fp);
+ return NULL;
+ }
+
+ /* verify owner */
+ if (st1.st_uid != st2.st_uid) {
+ lprintf(LOG_ERR, "File %s has invalid user id: %d != %d",
+ file, st1.st_uid, st2.st_uid);
+ fclose(fp);
+ return NULL;
+ }
+
+ /* verify inode */
+ if (st2.st_nlink != 1) {
+ lprintf(LOG_ERR, "File %s has invalid link count: %d != 1",
+ file, st2.st_nlink);
+ fclose(fp);
+ return NULL;
+ }
+#endif
+
+ return fp;
+}
+
+void
+ipmi_start_daemon(struct ipmi_intf *intf)
+{
+#ifndef WIN32
+ pid_t pid;
+ int fd, i;
+#ifdef SIGHUP
+ sigset_t sighup;
+#endif
+
+ /* if we are started from init no need to become daemon */
+ if (getppid() == 1)
+ return;
+
+#ifdef SIGHUP
+ sigemptyset(&sighup);
+ sigaddset(&sighup, SIGHUP);
+ if (sigprocmask(SIG_UNBLOCK, &sighup, NULL) < 0)
+ fprintf(stderr, "ERROR: could not unblock SIGHUP signal\n");
+ signal(SIGHUP, SIG_IGN);
+#endif
+#ifdef SIGTTOU
+ signal(SIGTTOU, SIG_IGN);
+#endif
+#ifdef SIGTTIN
+ signal(SIGTTIN, SIG_IGN);
+#endif
+#ifdef SIGQUIT
+ signal(SIGQUIT, SIG_IGN);
+#endif
+#ifdef SIGTSTP
+ signal(SIGTSTP, SIG_IGN);
+#endif
+
+ pid = (pid_t) fork();
+ if (pid < 0 || pid > 0)
+ exit(0);
+
+#if defined(SIGTSTP) && defined(TIOCNOTTY)
+ if (setpgid(0, getpid()) == -1)
+ exit(1);
+ if ((fd = open(_PATH_TTY, O_RDWR)) >= 0) {
+ ioctl(fd, TIOCNOTTY, NULL);
+ close(fd);
+ }
+#else
+ if (setpgid(0, 0) == -1)
+ exit(1);
+ pid = (pid_t) fork();
+ if (pid < 0 || pid > 0)
+ exit(0);
+#endif
+
+ i = chdir("/");
+ umask(0);
+
+ for (fd=0; fd<64; fd++) {
+ if (fd != intf->fd)
+ close(fd);
+ }
+
+ fd = open("/dev/null", O_RDWR);
+ i = dup(0);
+ i = dup(0);
+#endif
+}
diff --git a/lib/lanplus/inc/config.h b/lib/lanplus/inc/config.h
new file mode 100644
index 0000000..4ae9ee6
--- /dev/null
+++ b/lib/lanplus/inc/config.h
@@ -0,0 +1,144 @@
+/* config.h. Generated by configure. */
+/* config.h.in. Generated from configure.in by autoheader. */
+/* Define to 1 to enable all command line options. */
+#define ENABLE_ALL_OPTIONS 1
+/* Define to 1 for extra file security. */
+/* #undef ENABLE_FILE_SECURITY */
+/* Define to 1 if you have the `alarm' function. */
+#define HAVE_ALARM 1
+#ifdef WIN32
+#undef HAVE_ARPA_INET_H
+#undef HAVE_BYTESWAP_H
+#else
+/* Define to 1 if you have the <arpa/inet.h> header file. */
+#define HAVE_ARPA_INET_H 1
+/* Define to 1 if you have the <byteswap.h> header file. */
+#define HAVE_BYTESWAP_H 1
+#endif
+/* Define to 1 if libcrypto supports MD2. */
+#define HAVE_CRYPTO_MD2 1
+/* Define to 1 if libcrypto supports MD5. */
+#define HAVE_CRYPTO_MD5 1
+#ifdef WIN32
+#undef HAVE_DLFCN_H
+#undef HAVE_FCNTL_H
+#undef HAVE_INTTYPES_H
+#undef HAVE_NETDB_H
+#undef HAVE_NETINET_IN_H
+#undef HAVE_SYS_IOCTL_H
+#undef HAVE_OPENIPMI_H
+#else
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+/* Define to 1 if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+/* Define to 1 if you have the <sys/ipmi.h> header file. */
+/* #undef HAVE_FREEBSD_IPMI_H */
+/* Define to 1 if you have the <netdb.h> header file. */
+#define HAVE_NETDB_H 1
+/* Define to 1 if you have the <netinet/in.h> header file. */
+#define HAVE_NETINET_IN_H 1
+/* Define to 1 if you have the <linux/ipmi.h> header file. */
+#define HAVE_OPENIPMI_H 1
+/* Define to 1 if you have the <sys/ioctl.h> header file. */
+#define HAVE_SYS_IOCTL_H 1
+#endif
+/* Define to 1 if you have the `gethostbyname' function. */
+#define HAVE_GETHOSTBYNAME 1
+/* Define to 1 if you have the `getpassphrase' function. */
+/* #undef HAVE_GETPASSPHRASE */
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
+ to 0 otherwise. */
+#define HAVE_MALLOC 1
+/* Define to 1 if you have the `memmove' function. */
+#define HAVE_MEMMOVE 1
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+/* Define to 1 if you have the `memset' function. */
+#define HAVE_MEMSET 1
+/* Define to 1 if you have the <paths.h> header file. */
+#define HAVE_PATHS_H 1
+/* Define to 1 if readline present. */
+#define HAVE_READLINE 1
+/* Define to 1 if you have the `select' function. */
+#define HAVE_SELECT 1
+/* Define to 1 if you have the `socket' function. */
+#define HAVE_SOCKET 1
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+/* Define to 1 if you have the `strchr' function. */
+#define HAVE_STRCHR 1
+/* Define to 1 if you have the `strdup' function. */
+#define HAVE_STRDUP 1
+/* Define to 1 if you have the `strerror' function. */
+#define HAVE_STRERROR 1
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+/* Define to 1 if you have the <sys/byteorder.h> header file. */
+/* #undef HAVE_SYS_BYTEORDER_H */
+/* Define to 1 if you have the <sys/select.h> header file. */
+#define HAVE_SYS_SELECT_H 1
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#define HAVE_SYS_SOCKET_H 1
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+/* Define to 1 if you have <sys/termios.h>. */
+/* #undef HAVE_SYS_TERMIOS_H */
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+/* Define to 1 if you have <termios.h>. */
+#define HAVE_TERMIOS_H 1
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+/* Define to 1 to enable Solaris 10 BMC interface. */
+/* #undef IPMI_INTF_BMC */
+/* Define to 1 to enable Intel IMB interface. */
+/* #undef IPMI_INTF_IMB, or #define IPMI_INTF_IMB 1 */
+/* Define to 1 to enable LAN IPMIv1.5 interface. */
+// #define IPMI_INTF_LAN 1
+/* Define to 1 to enable LAN+ IPMIv2 interface. */
+#define IPMI_INTF_LANPLUS 1
+/* Define to 1 to enable Solaris 9 LIPMI interface. */
+/* #undef IPMI_INTF_LIPMI */
+/* Define to 1 to enable Linux OpenIPMI interface. */
+// #define IPMI_INTF_OPEN 1
+/* Name of package */
+#define PACKAGE "ipmitool"
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT ""
+/* Define to the full name of this package. */
+#define PACKAGE_NAME ""
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING ""
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME ""
+/* Define to the version of this package. */
+#define PACKAGE_VERSION ""
+/* Define to the type of arg 1 for `select'. */
+#define SELECT_TYPE_ARG1 int
+/* Define to the type of args 2, 3 and 4 for `select'. */
+#define SELECT_TYPE_ARG234 (fd_set *)
+/* Define to the type of arg 5 for `select'. */
+#define SELECT_TYPE_ARG5 (struct timeval *)
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+/* Version number of package */
+#define VERSION "1.8.7"
+/* Define to 1 if your processor stores words with the most significant byte
+ first (like Motorola and SPARC, unlike Intel and VAX). */
+/* #undef WORDS_BIGENDIAN */
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+ calls it, or to nothing if 'inline' is not supported under any name. */
+#ifndef __cplusplus
+/* #undef inline */
+#endif
+/* Define to rpl_malloc if the replacement function should be used. */
+/* #undef malloc */
diff --git a/lib/lanplus/inc/inttypes-win.h b/lib/lanplus/inc/inttypes-win.h
new file mode 100644
index 0000000..a049a3c
--- /dev/null
+++ b/lib/lanplus/inc/inttypes-win.h
@@ -0,0 +1,30 @@
+/*
+ * inttypes.h
+ *
+ */
+#ifdef WIN32
+
+#ifndef INTTYPES_WIN
+#define INTTYPES_WIN
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned int uint32_t;
+/*
+#if __WORDSIZE == 64
+typedef unsigned long int uint64_t;
+#else
+typedef unsigned long long uint64_t;
+#endif
+*/
+typedef uint32_t socklen_t;
+
+#ifndef __attribute__
+#define __attribute__(Spec) /*empty*/
+#endif
+#endif
+
+#else
+/* Linux */
+#include <inttypes.h>
+#endif
+/* end of inttypes.h */
diff --git a/lib/lanplus/inc/ipmitool/bswap.h b/lib/lanplus/inc/ipmitool/bswap.h
new file mode 100644
index 0000000..9948208
--- /dev/null
+++ b/lib/lanplus/inc/ipmitool/bswap.h
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+#ifndef IPMI_BSWAP_H
+#define IPMI_BSWAP_H
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#undef BSWAP_16
+#undef BSWAP_32
+
+#if HAVE_BYTESWAP_H
+# include <byteswap.h>
+# define BSWAP_16(x) bswap_16(x)
+# define BSWAP_32(x) bswap_32(x)
+#else
+# define BSWAP_16(x) ((((x) & 0xff00) >> 8) | (((x) & 0x00ff) << 8))
+# define BSWAP_32(x) ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) |\
+ (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
+#endif
+
+#endif /* IPMI_BSWAP_H */
diff --git a/lib/lanplus/inc/ipmitool/helper.h b/lib/lanplus/inc/ipmitool/helper.h
new file mode 100644
index 0000000..7f8a06e
--- /dev/null
+++ b/lib/lanplus/inc/ipmitool/helper.h
@@ -0,0 +1,102 @@
+/*
+ * 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.
+ */
+
+#ifndef IPMI_HELPER_H
+#define IPMI_HELPER_H
+
+#ifdef WIN32
+#include <inttypes-win.h>
+#include <stdio.h>
+#include <string.h>
+#define snprintf _snprintf
+#define vsnprintf _vsnprintf
+#define strncasecmp strnicmp
+#define strcasecmp _stricmp
+// #define strcasecmp stricmp
+// extern int stricmp(const char *__s1, const char *__s2);
+#else
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <string.h>
+#endif
+
+
+struct ipmi_intf;
+
+struct valstr {
+ uint16_t val;
+ const char * str;
+};
+struct oemvalstr {
+ uint16_t oem;
+ uint16_t val;
+ const char * str;
+};
+
+const char * val2str(uint16_t val, const struct valstr * vs);
+const char * oemval2str(uint16_t oem,uint16_t val, const struct oemvalstr * vs);
+uint16_t str2val(const char * str, const struct valstr * vs);
+void print_valstr(const struct valstr * vs, const char * title, int loglevel);
+void print_valstr_2col(const struct valstr * vs, const char * title, int loglevel);
+
+
+uint16_t buf2short(uint8_t * buf);
+uint32_t buf2long(uint8_t * buf);
+const char * buf2str(uint8_t * buf, int len);
+void printbuf(const uint8_t * buf, int len, const char * desc);
+uint8_t ipmi_csum(uint8_t * d, int s);
+FILE * ipmi_open_file(const char * file, int rw);
+void ipmi_start_daemon(struct ipmi_intf *intf);
+
+#define ipmi_open_file_read(file) ipmi_open_file(file, 0)
+#define ipmi_open_file_write(file) ipmi_open_file(file, 1)
+
+#ifndef WIN32
+#ifndef __min
+# define __min(a, b) ((a) < (b) ? (a) : (b))
+#endif
+
+#ifndef __max
+# define __max(a, b) ((a) > (b) ? (a) : (b))
+#endif
+#endif
+
+#ifndef __minlen
+# define __minlen(a, b) ({ int x=strlen(a); int y=strlen(b); (x < y) ? x : y;})
+#endif
+
+#ifndef __maxlen
+# define __maxlen(a, b) ({ int x=strlen(a); int y=strlen(b); (x > y) ? x : y;})
+#endif
+
+#endif /* IPMI_HELPER_H */
diff --git a/lib/lanplus/inc/ipmitool/ipmi.h b/lib/lanplus/inc/ipmitool/ipmi.h
new file mode 100644
index 0000000..39f3514
--- /dev/null
+++ b/lib/lanplus/inc/ipmitool/ipmi.h
@@ -0,0 +1,267 @@
+/*
+ * 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.
+ */
+
+#ifndef IPMI_H
+#define IPMI_H
+
+#ifdef WIN32
+#include <stdio.h>
+#include <inttypes-win.h>
+#include <ipmitool/helper.h>
+#include <ipmitool/ipmi_cc.h>
+#else
+#include <stdlib.h>
+#include <stdio.h>
+#include <inttypes.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <ipmitool/helper.h>
+#include <ipmitool/ipmi_cc.h>
+#endif
+
+#include <openssl/evp.h>
+
+#define IPMI_BUF_SIZE 1024
+
+/* From table 13.16 of the IPMI v2 specification */
+#define IPMI_PAYLOAD_TYPE_IPMI 0x00
+#define IPMI_PAYLOAD_TYPE_SOL 0x01
+#define IPMI_PAYLOAD_TYPE_OEM 0x02
+#define IPMI_PAYLOAD_TYPE_RMCP_OPEN_REQUEST 0x10
+#define IPMI_PAYLOAD_TYPE_RMCP_OPEN_RESPONSE 0x11
+#define IPMI_PAYLOAD_TYPE_RAKP_1 0x12
+#define IPMI_PAYLOAD_TYPE_RAKP_2 0x13
+#define IPMI_PAYLOAD_TYPE_RAKP_3 0x14
+#define IPMI_PAYLOAD_TYPE_RAKP_4 0x15
+
+extern int verbose;
+extern int csv_output;
+
+#ifndef _IPMI_RQ_
+#define _IPMI_RQ_
+struct ipmi_rq {
+ struct {
+ uint8_t netfn:6;
+ uint8_t lun:2;
+ uint8_t cmd;
+ uint8_t target_cmd;
+ uint16_t data_len;
+ uint8_t *data;
+ } msg;
+};
+#endif
+
+/*
+ * This is what the sendrcv_v2() function would take as an argument. The common case
+ * is for payload_type to be IPMI_PAYLOAD_TYPE_IPMI.
+ */
+struct ipmi_v2_payload {
+ uint16_t payload_length;
+ uint8_t payload_type;
+
+ union {
+
+ struct {
+ uint8_t rq_seq;
+ struct ipmi_rq *request;
+ } ipmi_request;
+
+ struct {
+ uint8_t rs_seq;
+ struct ipmi_rs *response;
+ } ipmi_response;
+
+ /* Only used internally by the lanplus interface */
+ struct {
+ uint8_t *request;
+ } open_session_request;
+
+ /* Only used internally by the lanplus interface */
+ struct {
+ uint8_t *message;
+ } rakp_1_message;
+
+ /* Only used internally by the lanplus interface */
+ struct {
+ uint8_t *message;
+ } rakp_2_message;
+
+ /* Only used internally by the lanplus interface */
+ struct {
+ uint8_t *message;
+ } rakp_3_message;
+
+ /* Only used internally by the lanplus interface */
+ struct {
+ uint8_t *message;
+ } rakp_4_message;
+
+ struct {
+ uint8_t data[IPMI_BUF_SIZE];
+ uint16_t character_count;
+ uint8_t packet_sequence_number;
+ uint8_t acked_packet_number;
+ uint8_t accepted_character_count;
+ uint8_t is_nack; /* bool */
+ uint8_t assert_ring_wor; /* bool */
+ uint8_t generate_break; /* bool */
+ uint8_t deassert_cts; /* bool */
+ uint8_t deassert_dcd_dsr; /* bool */
+ uint8_t flush_inbound; /* bool */
+ uint8_t flush_outbound; /* bool */
+ } sol_packet;
+
+ } payload;
+};
+
+struct ipmi_rq_entry {
+ struct ipmi_rq req;
+ struct ipmi_intf *intf;
+ uint8_t rq_seq;
+ uint8_t *msg_data;
+ int msg_len;
+ struct ipmi_rq_entry *next;
+};
+
+struct ipmi_rs {
+ uint8_t ccode;
+ uint8_t data[IPMI_BUF_SIZE];
+
+ /*
+ * Looks like this is the length of the entire packet, including the RMCP
+ * stuff, then modified to be the length of the extra IPMI message data
+ */
+ int data_len;
+
+ struct {
+ uint8_t netfn;
+ uint8_t cmd;
+ uint8_t seq;
+ uint8_t lun;
+ } msg;
+
+ struct {
+ uint8_t authtype;
+ uint32_t seq;
+ uint32_t id;
+ uint8_t bEncrypted; /* IPMI v2 only */
+ uint8_t bAuthenticated; /* IPMI v2 only */
+ uint8_t payloadtype; /* IPMI v2 only */
+ /* This is the total length of the payload or
+ IPMI message. IPMI v2.0 requires this to
+ be 2 bytes. Not really used for much. */
+ uint16_t msglen;
+ } session;
+
+ /*
+ * A union of the different possible payload meta-data
+ */
+ union {
+ struct {
+ uint8_t rq_addr;
+ uint8_t netfn;
+ uint8_t rq_lun;
+ uint8_t rs_addr;
+ uint8_t rq_seq;
+ uint8_t rs_lun;
+ uint8_t cmd;
+ } ipmi_response;
+ struct {
+ uint8_t message_tag;
+ uint8_t rakp_return_code;
+ uint8_t max_priv_level;
+ uint32_t console_id;
+ uint32_t bmc_id;
+ uint8_t auth_alg;
+ uint8_t integrity_alg;
+ uint8_t crypt_alg;
+ } open_session_response;
+ struct {
+ uint8_t message_tag;
+ uint8_t rakp_return_code;
+ uint32_t console_id;
+ uint8_t bmc_rand[16]; /* Random number generated by the BMC */
+ uint8_t bmc_guid[16];
+ uint8_t key_exchange_auth_code[EVP_MAX_MD_SIZE];
+ } rakp2_message;
+ struct {
+ uint8_t message_tag;
+ uint8_t rakp_return_code;
+ uint32_t console_id;
+ uint8_t integrity_check_value[EVP_MAX_MD_SIZE];
+ } rakp4_message;
+ struct {
+ uint8_t packet_sequence_number;
+ uint8_t acked_packet_number;
+ uint8_t accepted_character_count;
+ uint8_t is_nack; /* bool */
+ uint8_t transfer_unavailable; /* bool */
+ uint8_t sol_inactive; /* bool */
+ uint8_t transmit_overrun; /* bool */
+ uint8_t break_detected; /* bool */
+ } sol_packet;
+
+ } payload;
+};
+
+#define IPMI_NETFN_CHASSIS 0x0
+#define IPMI_NETFN_BRIDGE 0x2
+#define IPMI_NETFN_SE 0x4
+#define IPMI_NETFN_APP 0x6
+#define IPMI_NETFN_FIRMWARE 0x8
+#define IPMI_NETFN_STORAGE 0xa
+#define IPMI_NETFN_TRANSPORT 0xc
+#define IPMI_NETFN_PICMG 0x2C
+#define IPMI_NETFN_ISOL 0x34
+#define IPMI_NETFN_TSOL 0x30
+
+#define IPMI_BMC_SLAVE_ADDR 0x20
+#define IPMI_REMOTE_SWID 0x81
+
+
+/* These values are IANA numbers */
+typedef enum IPMI_OEM {
+ IPMI_OEM_UNKNOWN = 0,
+ IPMI_OEM_SUN = 42,
+ IPMI_OEM_NOKIA = 94,
+ IPMI_OEM_INTEL = 343,
+ IPMI_OEM_TYAN = 6653,
+ IPMI_OEM_NEWISYS = 9237,
+ IPMI_OEM_SUPERMICRO = 10876,
+ IPMI_OEM_GOOGLE = 11129,
+ IPMI_OEM_PICMG = 12634,
+ IPMI_OEM_KONTRON = 15000,
+} IPMI_OEM;
+
+extern const struct valstr completion_code_vals[];
+
+#endif /* IPMI_H */
diff --git a/lib/lanplus/inc/ipmitool/ipmi_cc.h b/lib/lanplus/inc/ipmitool/ipmi_cc.h
new file mode 100644
index 0000000..237b1ee
--- /dev/null
+++ b/lib/lanplus/inc/ipmitool/ipmi_cc.h
@@ -0,0 +1,76 @@
+/*
+ * 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.
+ */
+
+#ifndef IPMI_CC_H
+#define IPMI_CC_H
+
+/*
+ Thu Jan 11 09:32:41 2007
+ francois.isabelle@ca.kontron.com
+
+ I just noticed that most modules refer to IPMI completion codes using
+ hard coded values ...
+*/
+
+/*
+ * CC
+ * See IPMI specification table 5-2 Generic Completion Codes
+ */
+
+#define IPMI_CC_OK 0x00
+#define IPMI_CC_NODE_BUSY 0xc0
+#define IPMI_CC_INV_CMD 0xc1
+#define IPMI_CC_INV_CMD_FOR_LUN 0xc2
+#define IPMI_CC_TIMEOUT 0xc3
+#define IPMI_CC_OUT_OF_SPACE 0xc4
+#define IPMI_CC_RES_CANCELED 0xc5
+#define IPMI_CC_REQ_DATA_TRUNC 0xc6
+#define IPMI_CC_REQ_DATA_INV_LENGTH 0xc7
+#define IPMI_CC_REQ_DATA_FIELD_EXCEED 0xc8
+#define IPMI_CC_PARAM_OUT_OF_RANGE 0xc9
+#define IPMI_CC_CANT_RET_NUM_REQ_BYTES 0xca
+#define IPMI_CC_REQ_DATA_NOT_PRESENT 0xcb
+#define IPMI_CC_INV_DATA_FIELD_IN_REQ 0xcc
+#define IPMI_CC_ILL_SENSOR_OR_RECORD 0xcd
+#define IPMI_CC_RESP_COULD_NOT_BE_PRV 0xce
+#define IPMI_CC_CANT_RESP_DUPLI_REQ 0xcf
+#define IPMI_CC_CANT_RESP_SDRR_UPDATE 0xd0
+#define IPMI_CC_CANT_RESP_FIRM_UPDATE 0xd1
+#define IPMI_CC_CANT_RESP_BMC_INIT 0xd2
+#define IPMI_CC_DESTINATION_UNAVAILABLE 0xd3
+#define IPMI_CC_INSUFFICIENT_PRIVILEGES 0xd4
+#define IPMI_CC_NOT_SUPPORTED_PRESENT_STATE 0xd5
+#define IPMI_CC_ILLEGAL_COMMAND_DISABLED 0xd6
+#define IPMI_CC_UNSPECIFIED_ERROR 0xff
+
+
+#endif /*IPMI_CC_H*/
diff --git a/lib/lanplus/inc/ipmitool/ipmi_channel.h b/lib/lanplus/inc/ipmitool/ipmi_channel.h
new file mode 100644
index 0000000..00fda96
--- /dev/null
+++ b/lib/lanplus/inc/ipmitool/ipmi_channel.h
@@ -0,0 +1,229 @@
+/*
+ * 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.
+ */
+
+#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_SET_USER_ACCESS 0x43
+#define IPMI_GET_USER_ACCESS 0x44
+#define IPMI_SET_USER_NAME 0x45
+#define IPMI_GET_USER_NAME 0x46
+#define IPMI_SET_USER_PASSWORD 0x47
+#define IPMI_GET_CHANNEL_CIPHER_SUITES 0x54
+
+
+/*
+ * The Get Authentication Capabilities response structure
+ * From table 22-15 of the IPMI v2.0 spec
+ */
+struct get_channel_auth_cap_rsp {
+ uint8_t channel_number;
+#if WORDS_BIGENDIAN
+ uint8_t v20_data_available : 1; /* IPMI v2.0 data is available */
+ uint8_t __reserved1 : 1;
+ uint8_t enabled_auth_types : 6; /* IPMI v1.5 enabled auth types */
+#else
+ uint8_t enabled_auth_types : 6; /* IPMI v1.5 enabled auth types */
+ uint8_t __reserved1 : 1;
+ uint8_t v20_data_available : 1; /* IPMI v2.0 data is available */
+#endif
+#if WORDS_BIGENDIAN
+ uint8_t __reserved2 : 2;
+ uint8_t kg_status : 1; /* two-key login status */
+ uint8_t per_message_auth : 1; /* per-message authentication status */
+ uint8_t user_level_auth : 1; /* user-level authentication status */
+ uint8_t non_null_usernames : 1; /* one or more non-null users exist */
+ uint8_t null_usernames : 1; /* one or more null usernames non-null pwds */
+ uint8_t anon_login_enabled : 1; /* a null-named, null-pwd user exists */
+#else
+ uint8_t anon_login_enabled : 1; /* a null-named, null-pwd user exists */
+ uint8_t null_usernames : 1; /* one or more null usernames non-null pwds */
+ uint8_t non_null_usernames : 1; /* one or more non-null users exist */
+ uint8_t user_level_auth : 1; /* user-level authentication status */
+ uint8_t per_message_auth : 1; /* per-message authentication status */
+ uint8_t kg_status : 1; /* two-key login status */
+ uint8_t __reserved2 : 2;
+#endif
+#if WORDS_BIGENDIAN
+ uint8_t __reserved3 : 6;
+ uint8_t ipmiv15_support : 1; /* channel supports IPMI v1.5 connections */
+ uint8_t ipmiv20_support : 1; /* channel supports IPMI v2.0 connections */
+#else
+ uint8_t ipmiv20_support : 1; /* channel supports IPMI v2.0 connections */
+ uint8_t ipmiv15_support : 1; /* channel supports IPMI v1.5 connections */
+ uint8_t __reserved3 : 6;
+#endif
+ uint8_t oem_id[3]; /* IANA enterprise number for auth type */
+ uint8_t oem_aux_data; /* Additional OEM specific data for oem auths */
+} __attribute__ ((packed));
+
+
+
+/*
+ * The Get Channel Info response structure
+ * From table 22-29 of the IPMI v2.0 spec
+ */
+struct get_channel_info_rsp {
+#if WORDS_BIGENDIAN
+ uint8_t __reserved1 : 4;
+ uint8_t channel_number : 4; /* channel number */
+#else
+ uint8_t channel_number : 4; /* channel number */
+ uint8_t __reserved1 : 4;
+#endif
+#if WORDS_BIGENDIAN
+ uint8_t __reserved2 : 1;
+ uint8_t channel_medium : 7; /* Channel medium type per table 6-3 */
+#else
+ uint8_t channel_medium : 7; /* Channel medium type per table 6-3 */
+ uint8_t __reserved2 : 1;
+#endif
+#if WORDS_BIGENDIAN
+ uint8_t __reserved3 : 3;
+ uint8_t channel_protocol : 5; /* Channel protocol per table 6-2 */
+#else
+ uint8_t channel_protocol : 5; /* Channel protocol per table 6-2 */
+ uint8_t __reserved3 : 3;
+#endif
+#if WORDS_BIGENDIAN
+ uint8_t session_support : 2; /* Description of session support */
+ uint8_t active_sessions : 6; /* Count of active sessions */
+#else
+ uint8_t active_sessions : 6; /* Count of active sessions */
+ uint8_t session_support : 2; /* Description of session support */
+#endif
+ uint8_t vendor_id[3]; /* For OEM that specified the protocol */
+ uint8_t 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
+ uint8_t __reserved1 : 2;
+ uint8_t alerting : 1;
+ uint8_t per_message_auth : 1;
+ uint8_t user_level_auth : 1;
+ uint8_t access_mode : 3;
+#else
+ uint8_t access_mode : 3;
+ uint8_t user_level_auth : 1;
+ uint8_t per_message_auth : 1;
+ uint8_t alerting : 1;
+ uint8_t __reserved1 : 2;
+#endif
+#if WORDS_BIGENDIAN
+ uint8_t __reserved2 : 4;
+ uint8_t channel_priv_limit : 4; /* Channel privilege level limit */
+#else
+ uint8_t channel_priv_limit : 4; /* Channel privilege level limit */
+ uint8_t __reserved2 : 4;
+#endif
+} __attribute__ ((packed));
+
+
+struct get_user_access_rsp {
+#if WORDS_BIGENDIAN
+ uint8_t __reserved1 : 2;
+ uint8_t max_user_ids : 6;
+ uint8_t __reserved2 : 2;
+ uint8_t enabled_user_ids : 6;
+ uint8_t __reserved3 : 2;
+ uint8_t fixed_user_ids : 6;
+ uint8_t __reserved4 : 1;
+ uint8_t callin_callback : 1;
+ uint8_t link_auth : 1;
+ uint8_t ipmi_messaging : 1;
+ uint8_t privilege_limit : 4;
+#else
+ uint8_t max_user_ids : 6;
+ uint8_t __reserved1 : 2;
+ uint8_t enabled_user_ids : 6;
+ uint8_t __reserved2 : 2;
+ uint8_t fixed_user_ids : 6;
+ uint8_t __reserved3 : 2;
+ uint8_t privilege_limit : 4;
+ uint8_t ipmi_messaging : 1;
+ uint8_t link_auth : 1;
+ uint8_t callin_callback : 1;
+ uint8_t __reserved4 : 1;
+#endif
+} __attribute__ ((packed));
+
+struct set_user_access_data {
+#if WORDS_BIGENDIAN
+ uint8_t change_bits : 1;
+ uint8_t callin_callback : 1;
+ uint8_t link_auth : 1;
+ uint8_t ipmi_messaging : 1;
+ uint8_t channel : 4;
+ uint8_t __reserved1 : 2;
+ uint8_t user_id : 6;
+ uint8_t __reserved2 : 4;
+ uint8_t privilege_limit : 4;
+ uint8_t __reserved3 : 4;
+ uint8_t session_limit : 4;
+#else
+ uint8_t channel : 4;
+ uint8_t ipmi_messaging : 1;
+ uint8_t link_auth : 1;
+ uint8_t callin_callback : 1;
+ uint8_t change_bits : 1;
+ uint8_t user_id : 6;
+ uint8_t __reserved1 : 2;
+ uint8_t privilege_limit : 4;
+ uint8_t __reserved2 : 4;
+ uint8_t session_limit : 4;
+ uint8_t __reserved3 : 4;
+#endif
+} __attribute__ ((packed));
+
+uint8_t ipmi_get_channel_medium(struct ipmi_intf * intf, uint8_t channel);
+uint8_t ipmi_current_channel_medium(struct ipmi_intf * intf);
+int ipmi_channel_main(struct ipmi_intf * intf, int argc, char ** argv);
+int ipmi_get_channel_auth_cap(struct ipmi_intf * intf, uint8_t channel, uint8_t priv);
+int ipmi_get_channel_info(struct ipmi_intf * intf, uint8_t channel);
+
+#endif /*IPMI_CHANNEL_H*/
diff --git a/lib/lanplus/inc/ipmitool/ipmi_chassis.h b/lib/lanplus/inc/ipmitool/ipmi_chassis.h
new file mode 100644
index 0000000..3f56924
--- /dev/null
+++ b/lib/lanplus/inc/ipmitool/ipmi_chassis.h
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+#ifndef IPMI_CHASSIS_H
+#define IPMI_CHASSIS_H
+
+#include <ipmitool/ipmi.h>
+
+#define IPMI_CHASSIS_CTL_POWER_DOWN 0x0
+#define IPMI_CHASSIS_CTL_POWER_UP 0x1
+#define IPMI_CHASSIS_CTL_POWER_CYCLE 0x2
+#define IPMI_CHASSIS_CTL_HARD_RESET 0x3
+#define IPMI_CHASSIS_CTL_PULSE_DIAG 0x4
+#define IPMI_CHASSIS_CTL_ACPI_SOFT 0x5
+
+#define IPMI_CHASSIS_POLICY_NO_CHANGE 0x3
+#define IPMI_CHASSIS_POLICY_ALWAYS_ON 0x2
+#define IPMI_CHASSIS_POLICY_PREVIOUS 0x1
+#define IPMI_CHASSIS_POLICY_ALWAYS_OFF 0x0
+
+int ipmi_chassis_power_status(struct ipmi_intf * intf);
+int ipmi_chassis_power_control(struct ipmi_intf * intf, uint8_t ctl);
+int ipmi_chassis_main(struct ipmi_intf * intf, int argc, char ** argv);
+int ipmi_power_main(struct ipmi_intf * intf, int argc, char ** argv);
+
+#endif /*IPMI_CHASSIS_H*/
diff --git a/lib/lanplus/inc/ipmitool/ipmi_constants.h b/lib/lanplus/inc/ipmitool/ipmi_constants.h
new file mode 100644
index 0000000..654e0ae
--- /dev/null
+++ b/lib/lanplus/inc/ipmitool/ipmi_constants.h
@@ -0,0 +1,136 @@
+/*
+ * 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.
+ */
+
+#ifndef IPMI_CONSTANTS_H
+#define IPMI_CONSTANTS_H
+
+
+/*
+ * COMMANDS
+ */
+#define IPMI_GET_SDR_REPOSITORY_INFO 0x20
+#define IMPI_SOL_ACTIVATING 0x20
+#define IMPI_SET_SOL_CONFIG_PARAMETERS 0x21
+#define IMPI_GET_SOL_CONFIG_PARAMETERS 0x22
+#define IPMI_SET_USER_ACCESS 0x43
+#define IPMI_GET_USER_ACCESS 0x44
+#define IPMI_SET_USER_NAME 0x45
+#define IPMI_GET_USER_NAME 0x46
+#define IPMI_SET_USER_PASSWORD 0x47
+#define IPMI_ACTIVATE_PAYLOAD 0x48
+#define IPMI_DEACTIVATE_PAYLOAD 0x49
+#define IPMI_SUSPEND_RESUME_PAYLOAD_ENCRYPTYION 0x55
+#define IPMI_GET_SEL_TIME 0x48
+#define IPMI_SET_SEL_TIME 0x49
+#define IPMI_SET_USER_PAYLOAD_ACCESS 0x4c
+#define IPMI_GET_USER_PAYLOAD_ACCESS 0x4d
+
+#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
+
+#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 IPMI_SESSION_AUTHTYPE_KEY
+#define IPMI_SESSION_AUTHTYPE_OEM 0x5
+#define IPMI_SESSION_AUTHTYPE_RMCP_PLUS 0x6
+
+#define IPMI_SESSION_PRIV_UNSPECIFIED 0x0
+#define IPMI_SESSION_PRIV_CALLBACK 0x1
+#define IPMI_SESSION_PRIV_USER 0x2
+#define IPMI_SESSION_PRIV_OPERATOR 0x3
+#define IPMI_SESSION_PRIV_ADMIN 0x4
+#define IPMI_SESSION_PRIV_OEM 0x5
+
+#define IPMI_SET_IN_PROGRESS_SET_COMPLETE 0x00
+#define IPMI_SET_IN_PROGRESS_IN_PROGRESS 0x01
+#define IPMI_SET_IN_PROGRESS_COMMIT_WRITE 0x02
+
+#define IPMI_CHANNEL_MEDIUM_RESERVED 0x0
+#define IPMI_CHANNEL_MEDIUM_IPMB_I2C 0x1
+#define IPMI_CHANNEL_MEDIUM_ICMB_1 0x2
+#define IPMI_CHANNEL_MEDIUM_ICMB_09 0x3
+#define IPMI_CHANNEL_MEDIUM_LAN 0x4
+#define IPMI_CHANNEL_MEDIUM_SERIAL 0x5
+#define IPMI_CHANNEL_MEDIUM_LAN_OTHER 0x6
+#define IPMI_CHANNEL_MEDIUM_SMBUS_PCI 0x7
+#define IPMI_CHANNEL_MEDIUM_SMBUS_1 0x8
+#define IPMI_CHANNEL_MEDIUM_SMBUS_2 0x9
+#define IPMI_CHANNEL_MEDIUM_USB_1 0xa
+#define IPMI_CHANNEL_MEDIUM_USB_2 0xb
+#define IPMI_CHANNEL_MEDIUM_SYSTEM 0xc
+
+#define IPMI_CHASSIS_CTL_POWER_DOWN 0x0
+#define IPMI_CHASSIS_CTL_POWER_UP 0x1
+#define IPMI_CHASSIS_CTL_POWER_CYCLE 0x2
+#define IPMI_CHASSIS_CTL_HARD_RESET 0x3
+#define IPMI_CHASSIS_CTL_PULSE_DIAG 0x4
+#define IPMI_CHASSIS_CTL_ACPI_SOFT 0x5
+
+#define IPMI_CHASSIS_POLICY_NO_CHANGE 0x3
+#define IPMI_CHASSIS_POLICY_ALWAYS_ON 0x2
+#define IPMI_CHASSIS_POLICY_PREVIOUS 0x1
+#define IPMI_CHASSIS_POLICY_ALWAYS_OFF 0x0
+
+#define IPMI_CHASSIS_BOOTPARAM_SET_IN_PROGRESS 0
+#define IPMI_CHASSIS_BOOTPARAM_SVCPART_SELECT 1
+#define IPMI_CHASSIS_BOOTPARAM_SVCPART_SCAN 2
+#define IPMI_CHASSIS_BOOTPARAM_FLAG_VALID 3
+#define IPMI_CHASSIS_BOOTPARAM_INFO_ACK 4
+#define IPMI_CHASSIS_BOOTPARAM_BOOT_FLAGS 5
+#define IPMI_CHASSIS_BOOTPARAM_INIT_INFO 6
+#define IPMI_CHASSIS_BOOTPARAM_INIT_MBOX 7
+
+/* From table 13-17 of the IPMI v2 specification */
+#define IPMI_AUTH_RAKP_NONE 0x00
+#define IPMI_AUTH_RAKP_HMAC_SHA1 0x01
+#define IPMI_AUTH_RAKP_HMAC_MD5 0x02
+#define IPMI_AUTH_RAKP_HMAC_SHA256 0x03
+
+/* From table 13-18 of the IPMI v2 specification */
+#define IPMI_INTEGRITY_NONE 0x00
+#define IPMI_INTEGRITY_HMAC_SHA1_96 0x01
+#define IPMI_INTEGRITY_HMAC_MD5_128 0x02
+#define IPMI_INTEGRITY_MD5_128 0x03
+#define IPMI_INTEGRITY_HMAC_SHA256_128 0x04
+
+/* From table 13-19 of the IPMI v2 specfication */
+#define IPMI_CRYPT_NONE 0x00
+#define IPMI_CRYPT_AES_CBC_128 0x01
+#define IPMI_CRYPT_XRC4_128 0x02
+#define IPMI_CRYPT_XRC4_40 0x03
+
+#endif /*IPMI_CONSTANTS_H*/
diff --git a/lib/lanplus/inc/ipmitool/ipmi_entity.h b/lib/lanplus/inc/ipmitool/ipmi_entity.h
new file mode 100644
index 0000000..29f44d2
--- /dev/null
+++ b/lib/lanplus/inc/ipmitool/ipmi_entity.h
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+#ifndef IPMI_ENTITY_H
+#define IPMI_ENTITY_H
+
+struct entity_id {
+ uint8_t id; /* physical entity id */
+#if WORDS_BIGENDIAN
+ uint8_t logical : 1; /* physical/logical */
+ uint8_t instance : 7; /* instance number */
+#else
+ uint8_t instance : 7; /* instance number */
+ uint8_t logical : 1; /* physical/logical */
+#endif
+} __attribute__ ((packed));
+
+#endif /* IPMI_ENTITY_H */
diff --git a/lib/lanplus/inc/ipmitool/ipmi_event.h b/lib/lanplus/inc/ipmitool/ipmi_event.h
new file mode 100644
index 0000000..e78d453
--- /dev/null
+++ b/lib/lanplus/inc/ipmitool/ipmi_event.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind.
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
+ * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE
+ * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
+ * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
+ * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
+ * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
+ * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
+ * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
+ * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#ifndef IPMI_EVENT_H
+#define IPMI_EVENT_H
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <ipmitool/ipmi.h>
+
+#define EVENT_DIR_ASSERT 0
+#define EVENT_DIR_DEASSERT 1
+
+struct platform_event_msg {
+ uint8_t evm_rev;
+ uint8_t sensor_type;
+ uint8_t sensor_num;
+#if WORDS_BIGENDIAN
+ uint8_t event_dir : 1;
+ uint8_t event_type : 7;
+#else
+ uint8_t event_type : 7;
+ uint8_t event_dir : 1;
+#endif
+ uint8_t event_data[3];
+} __attribute__((packed));
+
+int ipmi_event_main(struct ipmi_intf *, int, char **);
+
+#endif /*IPMI_EVENT_H*/
diff --git a/lib/lanplus/inc/ipmitool/ipmi_firewall.h b/lib/lanplus/inc/ipmitool/ipmi_firewall.h
new file mode 100644
index 0000000..f18770e
--- /dev/null
+++ b/lib/lanplus/inc/ipmitool/ipmi_firewall.h
@@ -0,0 +1,106 @@
+/*
+ * 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.
+ */
+
+#ifndef IPMI_FIREWALL_H
+#define IPMI_FIREWALL_H
+
+#include <ipmitool/ipmi.h>
+
+int ipmi_firewall_main(struct ipmi_intf *, int, char **);
+
+#define BMC_GET_NETFN_SUPPORT 0x09
+#define BMC_GET_COMMAND_SUPPORT 0x0A
+#define BMC_GET_COMMAND_SUBFUNCTION_SUPPORT 0x0B
+#define BMC_GET_CONFIGURABLE_COMMANDS 0x0C
+#define BMC_GET_CONFIGURABLE_COMMAND_SUBFUNCTIONS 0x0D
+#define BMC_SET_COMMAND_ENABLES 0x60
+#define BMC_GET_COMMAND_ENABLES 0x61
+#define BMC_SET_COMMAND_SUBFUNCTION_ENABLES 0x62
+#define BMC_GET_COMMAND_SUBFUNCTION_ENABLES 0x63
+#define BMC_OEM_NETFN_IANA_SUPPORT 0x64
+
+#define SET_COMMAND_ENABLE_BYTE (BMC_SET_COMMAND_ENABLES / 8)
+#define SET_COMMAND_ENABLE_BIT (BMC_SET_COMMAND_ENABLES % 8)
+
+#define MAX_LUN 4
+#define MAX_NETFN 64
+#define MAX_NETFN_PAIR (MAX_NETFN/2)
+#define MAX_COMMAND 256
+#define MAX_SUBFN 32
+#define MAX_COMMAND_BYTES (MAX_COMMAND>>3)
+#define MAX_SUBFN_BYTES (MAX_SUBFN>>3)
+
+// support is a bitfield with the following bits set...
+#define BIT_AVAILABLE 0x01
+#define BIT_CONFIGURABLE 0x02
+#define BIT_ENABLED 0x04
+
+extern int verbose;
+
+struct command_support {
+ unsigned char support;
+ unsigned char version[3];
+ unsigned char subfn_support[MAX_SUBFN_BYTES];
+ unsigned char subfn_config[MAX_SUBFN_BYTES];
+ unsigned char subfn_enable[MAX_SUBFN_BYTES];
+};
+struct lun_netfn_support {
+ unsigned char support;
+ struct command_support command[MAX_COMMAND];
+ unsigned char command_mask[MAX_COMMAND_BYTES];
+ unsigned char config_mask[MAX_COMMAND_BYTES];
+ unsigned char enable_mask[MAX_COMMAND_BYTES];
+};
+struct lun_support {
+ unsigned char support;
+ struct lun_netfn_support netfn[MAX_NETFN_PAIR];
+};
+struct bmc_fn_support {
+ struct lun_support lun[MAX_LUN];
+};
+struct ipmi_function_params {
+ int channel;
+ int lun;
+ int netfn;
+ int command;
+ int subfn;
+ unsigned char force;
+};
+
+static inline int bit_test(const unsigned char * bf, int n) {
+ return !!(bf[n>>3]&(1<<(n%8)));
+}
+static inline void bit_set(unsigned char * bf, int n, int v) {
+ bf[n>>3] = (bf[n>>3] & ~(1<<(n%8))) | ((v?1:0)<<(n%8));
+}
+
+#endif /*IPMI_FIREWALL_H */
diff --git a/lib/lanplus/inc/ipmitool/ipmi_fru.h b/lib/lanplus/inc/ipmitool/ipmi_fru.h
new file mode 100644
index 0000000..0fe594a
--- /dev/null
+++ b/lib/lanplus/inc/ipmitool/ipmi_fru.h
@@ -0,0 +1,381 @@
+/*
+ * 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.
+ */
+
+#ifndef IPMI_FRU_H
+#define IPMI_FRU_H
+
+#ifdef WIN32
+#include <inttypes-win.h>
+#else
+#include <inttypes.h>
+#endif
+#include <ipmitool/ipmi.h>
+#include <ipmitool/ipmi_sdr.h>
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define GET_FRU_INFO 0x10
+#define GET_FRU_DATA 0x11
+#define SET_FRU_DATA 0x12
+
+enum {
+ FRU_CHASSIS_PARTNO,
+ FRU_CHASSIS_SERIAL,
+ FRU_BOARD_MANUF,
+ FRU_BOARD_PRODUCT,
+ FRU_BOARD_SERIAL,
+ FRU_BOARD_PARTNO,
+ FRU_PRODUCT_MANUF,
+ FRU_PRODUCT_NAME,
+ FRU_PRODUCT_PARTNO,
+ FRU_PRODUCT_VERSION,
+ FRU_PRODUCT_SERIAL,
+ FRU_PRODUCT_ASSET,
+};
+
+struct fru_info {
+ uint16_t size;
+ uint8_t access:1;
+} __attribute__ ((packed));
+
+struct fru_header {
+ uint8_t version;
+ struct {
+ uint8_t internal;
+ uint8_t chassis;
+ uint8_t board;
+ uint8_t product;
+ uint8_t multi;
+ } offset;
+ uint8_t pad;
+ uint8_t checksum;
+} __attribute__ ((packed));
+
+struct fru_area_chassis {
+ uint8_t area_ver;
+ uint8_t type;
+ uint16_t area_len;
+ char *part;
+ char *serial;
+};
+
+struct fru_area_board {
+ uint8_t area_ver;
+ uint8_t lang;
+ uint16_t area_len;
+ uint32_t mfg_date_time;
+ char *mfg;
+ char *prod;
+ char *serial;
+ char *part;
+ char *fru;
+};
+
+struct fru_area_product {
+ uint8_t area_ver;
+ uint8_t lang;
+ uint16_t area_len;
+ char *mfg;
+ char *name;
+ char *part;
+ char *version;
+ char *serial;
+ char *asset;
+ char *fru;
+};
+
+struct fru_multirec_header {
+#define FRU_RECORD_TYPE_POWER_SUPPLY_INFORMATION 0x00
+#define FRU_RECORD_TYPE_DC_OUTPUT 0x01
+#define FRU_RECORD_TYPE_DC_LOAD 0x02
+#define FRU_RECORD_TYPE_MANAGEMENT_ACCESS 0x03
+#define FRU_RECORD_TYPE_BASE_COMPATIBILITY 0x04
+#define FRU_RECORD_TYPE_EXTENDED_COMPATIBILITY 0x05
+#define FRU_RECORD_TYPE_OEM_EXTENSION 0xc0
+ uint8_t type;
+ uint8_t format;
+ uint8_t len;
+ uint8_t record_checksum;
+ uint8_t header_checksum;
+} __attribute__ ((packed));
+
+struct fru_multirec_powersupply {
+#if WORDS_BIGENDIAN
+ uint16_t capacity;
+#else
+ uint16_t capacity:12;
+ uint16_t __reserved1:4;
+#endif
+ uint16_t peak_va;
+ uint8_t inrush_current;
+ uint8_t inrush_interval;
+ uint16_t lowend_input1;
+ uint16_t highend_input1;
+ uint16_t lowend_input2;
+ uint16_t highend_input2;
+ uint8_t lowend_freq;
+ uint8_t highend_freq;
+ uint8_t dropout_tolerance;
+#if WORDS_BIGENDIAN
+ uint8_t __reserved2:3;
+ uint8_t tach:1;
+ uint8_t hotswap:1;
+ uint8_t autoswitch:1;
+ uint8_t pfc:1;
+ uint8_t predictive_fail:1;
+#else
+ uint8_t predictive_fail:1;
+ uint8_t pfc:1;
+ uint8_t autoswitch:1;
+ uint8_t hotswap:1;
+ uint8_t tach:1;
+ uint8_t __reserved2:3;
+#endif
+ uint16_t peak_cap_ht;
+#if WORDS_BIGENDIAN
+ uint8_t combined_voltage1:4;
+ uint8_t combined_voltage2:4;
+#else
+ uint8_t combined_voltage2:4;
+ uint8_t combined_voltage1:4;
+#endif
+ uint16_t combined_capacity;
+ uint8_t rps_threshold;
+} __attribute__ ((packed));
+
+static const char *combined_voltage_desc[] __attribute__ ((unused)) = {
+"12 V", "-12 V", "5 V", "3.3 V"};
+
+struct fru_multirec_dcoutput {
+#if WORDS_BIGENDIAN
+ uint8_t standby:1;
+ uint8_t __reserved1:3;
+ uint8_t output_number:4;
+#else
+ uint8_t output_number:4;
+ uint8_t __reserved1:3;
+ uint8_t standby:1;
+#endif
+ short nominal_voltage;
+ short max_neg_dev;
+ short max_pos_dev;
+ uint16_t ripple_and_noise;
+ uint16_t min_current;
+ uint16_t max_current;
+} __attribute__ ((packed));
+
+struct fru_multirec_dcload {
+#if WORDS_BIGENDIAN
+ uint8_t __reserved1:4;
+ uint8_t output_number:4;
+#else
+ uint8_t output_number:4;
+ uint8_t __reserved1:4;
+#endif
+ short nominal_voltage;
+ short min_voltage;
+ short max_voltage;
+ uint16_t ripple_and_noise;
+ uint16_t min_current;
+ uint16_t max_current;
+} __attribute__ ((packed));
+
+struct fru_multirec_oem_header {
+ unsigned char mfg_id[3];
+#define FRU_PICMG_BACKPLANE_P2P 0x04
+#define FRU_PICMG_ADDRESS_TABLE 0x10
+#define FRU_PICMG_SHELF_POWER_DIST 0x11
+#define FRU_PICMG_SHELF_ACTIVATION 0x12
+#define FRU_PICMG_SHMC_IP_CONN 0x13
+#define FRU_PICMG_BOARD_P2P 0x14
+#define FRU_AMC_CURRENT 0x16
+#define FRU_AMC_ACTIVATION 0x17
+#define FRU_AMC_CARRIER_P2P 0x18
+#define FRU_AMC_P2P 0x19
+#define FRU_AMC_CARRIER_INFO 0x1a
+ unsigned char record_id;
+ unsigned char record_version;
+} __attribute__ ((packed));
+
+struct fru_picmgext_guid {
+ unsigned char guid[16];
+} __attribute__ ((packed));
+
+struct fru_picmgext_link_desc {
+#ifndef WORDS_BIGENDIAN
+ unsigned int designator:12;
+#define FRU_PICMGEXT_LINK_TYPE_BASE 0x01
+#define FRU_PICMGEXT_LINK_TYPE_FABRIC_ETHERNET 0x02
+#define FRU_PICMGEXT_LINK_TYPE_FABRIC_INFINIBAND 0x03
+#define FRU_PICMGEXT_LINK_TYPE_FABRIC_STAR 0x04
+#define FRU_PICMGEXT_LINK_TYPE_PCIE 0x05
+ unsigned int type:8;
+ unsigned int ext:4;
+ unsigned int grouping:8;
+#else
+ unsigned int grouping:8;
+ unsigned int ext:4;
+#define FRU_PICMGEXT_LINK_TYPE_BASE 0x01
+#define FRU_PICMGEXT_LINK_TYPE_FABRIC_ETHERNET 0x02
+#define FRU_PICMGEXT_LINK_TYPE_FABRIC_INFINIBAND 0x03
+#define FRU_PICMGEXT_LINK_TYPE_FABRIC_STAR 0x04
+#define FRU_PICMGEXT_LINK_TYPE_PCIE 0x05
+ unsigned int type:8;
+ unsigned int designator:12;
+#endif
+} __attribute__ ((packed));
+
+
+#define FRU_PICMGEXT_AMC_LINK_TYPE_RESERVED 0x00
+#define FRU_PICMGEXT_AMC_LINK_TYPE_RESERVED1 0x01
+#define FRU_PICMGEXT_AMC_LINK_TYPE_PCI_EXPRESS 0x02
+#define FRU_PICMGEXT_AMC_LINK_TYPE_ADVANCED_SWITCHING1 0x03
+#define FRU_PICMGEXT_AMC_LINK_TYPE_ADVANCED_SWITCHING2 0x04
+#define FRU_PICMGEXT_AMC_LINK_TYPE_ETHERNET 0x05
+#define FRU_PICMGEXT_AMC_LINK_TYPE_RAPIDIO 0x06
+#define FRU_PICMGEXT_AMC_LINK_TYPE_STORAGE 0x07
+
+/* This is used in command, not in FRU */
+struct fru_picmgext_amc_link_info {
+ unsigned char linkInfo[3];
+} __attribute__ ((packed));
+
+struct fru_picmgext_amc_link_desc_core {
+#ifndef WORDS_BIGENDIAN
+ unsigned int designator:12;
+ unsigned int type:8;
+ unsigned int ext:4;
+ unsigned int grouping:8;
+#else
+ unsigned int grouping:8;
+ unsigned int ext:4;
+ unsigned int type:8;
+ unsigned int designator:12;
+#endif
+} __attribute__ ((packed));
+
+struct fru_picmgext_amc_link_desc_extra {
+#ifndef WORDS_BIGENDIAN
+ unsigned char asymetricMatch:2;
+ unsigned char reserved:6;
+#else
+ unsigned char reserved:6;
+ unsigned char asymetricMatch:2;
+#endif
+} __attribute__ ((packed));
+
+
+struct fru_picmgext_amc_link_desc {
+#ifndef WORDS_BIGENDIAN
+ struct fru_picmgext_amc_link_desc_core core;/* lsb */
+ struct fru_picmgext_amc_link_desc_extra extra;
+#else
+ struct fru_picmgext_amc_link_desc_extra extra;
+ struct fru_picmgext_amc_link_desc_core core;/* lsb */
+#endif
+} __attribute__ ((packed));
+
+
+struct fru_picmgext_chn_desc {
+#ifndef WORDS_BIGENDIAN
+ unsigned char remote_slot:8;
+ unsigned char remote_chn:5;
+ unsigned char local_chn:5;
+ unsigned char:6;
+#else
+ unsigned char:6;
+ unsigned char local_chn:5;
+ unsigned char remote_chn:5;
+ unsigned char remote_slot:8;
+#endif
+} __attribute__ ((packed));
+
+struct fru_picmgext_slot_desc {
+ unsigned char chan_type;
+ unsigned char slot_addr;
+ unsigned char chn_count;
+} __attribute__ ((packed));
+
+#define FRU_PICMGEXT_DESIGN_IF_BASE 0x00
+#define FRU_PICMGEXT_DESIGN_IF_FABRIC 0x01
+#define FRU_PICMGEXT_DESIGN_IF_UPDATE_CHANNEL 0x02
+#define FRU_PICMGEXT_DESIGN_IF_RESERVED 0x03
+
+struct fru_picmgext_carrier_activation_record {
+ unsigned short max_internal_curr;
+ unsigned char allowance_for_readiness;
+ unsigned char module_activation_record_count;
+} __attribute__ ((packed));
+
+struct fru_picmgext_activation_record {
+ unsigned char ibmb_addr;
+ unsigned char max_module_curr;
+ unsigned char reserved;
+} __attribute__ ((packed));
+
+struct fru_picmgext_carrier_p2p_record {
+ unsigned char resource_id;
+ unsigned char p2p_count;
+} __attribute__ ((packed));
+
+struct fru_picmgext_carrier_p2p_descriptor {
+#ifndef WORDS_BIGENDIAN
+ unsigned char remote_resource_id;
+ unsigned short remote_port:5;
+ unsigned short local_port:5;
+ unsigned short reserved:6;
+#else
+ unsigned short reserved:6;
+ unsigned short local_port:5;
+ unsigned short remote_port:5;
+ unsigned char remote_resource_id;
+#endif
+} __attribute__ ((packed));
+
+static const char *chassis_type_desc[] __attribute__ ((unused)) = {
+"Unspecified", "Other", "Unknown",
+ "Desktop", "Low Profile Desktop", "Pizza Box",
+ "Mini Tower", "Tower",
+ "Portable", "LapTop", "Notebook", "Hand Held",
+ "Docking Station", "All in One", "Sub Notebook",
+ "Space-saving", "Lunch Box", "Main Server Chassis",
+ "Expansion Chassis", "SubChassis", "Bus Expansion Chassis",
+ "Peripheral Chassis", "RAID Chassis", "Rack Mount Chassis"};
+
+int ipmi_fru_main(struct ipmi_intf *intf, int argc, char **argv);
+int ipmi_fru_print(struct ipmi_intf *intf, struct sdr_record_fru_locator *fru);
+int ipmi_spd_print(uint8_t *data, int len);
+int ipmi_spd_print_fru(struct ipmi_intf * intf, uint8_t id);
+
+#endif /* IPMI_FRU_H */
diff --git a/lib/lanplus/inc/ipmitool/ipmi_fwum.h b/lib/lanplus/inc/ipmitool/ipmi_fwum.h
new file mode 100644
index 0000000..1170abe
--- /dev/null
+++ b/lib/lanplus/inc/ipmitool/ipmi_fwum.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind.
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
+ * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE
+ * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
+ * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
+ * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
+ * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
+ * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
+ * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
+ * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#ifndef IPMI_KFWUM_H
+#define IPMI_KFWUM_H
+
+#ifdef WIN32
+#include <inttypes-win.h>
+#else
+#include <inttypes.h>
+#endif
+#include <ipmitool/ipmi.h>
+
+
+int ipmi_fwum_main(struct ipmi_intf *, int, char **);
+
+#endif /* IPMI_KFWUM_H */
diff --git a/lib/lanplus/inc/ipmitool/ipmi_hpmfwupg.h b/lib/lanplus/inc/ipmitool/ipmi_hpmfwupg.h
new file mode 100644
index 0000000..4739d58
--- /dev/null
+++ b/lib/lanplus/inc/ipmitool/ipmi_hpmfwupg.h
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+#ifndef IPMI_HPMFWUPG_H
+#define IPMI_HPMFWUPG_H
+
+#ifdef WIN32
+#include <inttypes-win.h>
+#else
+#include <inttypes.h>
+#endif
+#include <ipmitool/ipmi.h>
+
+int ipmi_hpmfwupg_main(struct ipmi_intf *, int, char **);
+
+#endif /* IPMI_KFWUM_H */
diff --git a/lib/lanplus/inc/ipmitool/ipmi_intf.h b/lib/lanplus/inc/ipmitool/ipmi_intf.h
new file mode 100644
index 0000000..db1ffd5
--- /dev/null
+++ b/lib/lanplus/inc/ipmitool/ipmi_intf.h
@@ -0,0 +1,224 @@
+/*
+ * 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.
+ */
+
+#ifndef IPMI_INTF_H
+#define IPMI_INTF_H
+
+#include <ipmitool/ipmi.h>
+#include <ipmitool/ipmi_oem.h>
+#include <ipmitool/ipmi_constants.h>
+
+#ifdef WIN32
+#include <windows.h>
+#include <winsock.h>
+#include <inttypes-win.h>
+#else
+#include <sys/types.h>
+#include <arpa/inet.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#endif
+
+#include <openssl/evp.h>
+#include <openssl/sha.h>
+
+#ifdef MOVED
+// moved this to "lanplus_defs.h"
+/*
+ * An enumeration that describes every possible session state for
+ * an IPMIv2 / RMCP+ session.
+ */
+enum LANPLUS_SESSION_STATE {
+ LANPLUS_STATE_PRESESSION = 0,
+ LANPLUS_STATE_OPEN_SESSION_SENT,
+ LANPLUS_STATE_OPEN_SESSION_RECEIEVED,
+ LANPLUS_STATE_RAKP_1_SENT,
+ LANPLUS_STATE_RAKP_2_RECEIVED,
+ LANPLUS_STATE_RAKP_3_SENT,
+ LANPLUS_STATE_ACTIVE,
+ LANPLUS_STATE_CLOSE_SENT,
+};
+
+#define IPMI_AUTHCODE_BUFFER_SIZE 20 // KG or KUID
+#define IPMI_SIK_BUFFER_SIZE EVP_MAX_MD_SIZE
+#define IPMI_KG_BUFFER_SIZE 21 /* key plus null byte */
+
+struct ipmi_session {
+ uint8_t hostname[64];
+ uint8_t username[17];
+ uint8_t authcode[IPMI_AUTHCODE_BUFFER_SIZE + 1];
+ uint8_t challenge[16];
+ uint8_t authtype;
+ uint8_t authtype_set;
+#define IPMI_AUTHSTATUS_PER_MSG_DISABLED 0x10
+#define IPMI_AUTHSTATUS_PER_USER_DISABLED 0x08
+#define IPMI_AUTHSTATUS_NONNULL_USERS_ENABLED 0x04
+#define IPMI_AUTHSTATUS_NULL_USERS_ENABLED 0x02
+#define IPMI_AUTHSTATUS_ANONYMOUS_USERS_ENABLED 0x01
+ uint8_t authstatus;
+ uint8_t authextra;
+ uint8_t privlvl;
+ uint8_t cipher_suite_id;
+ char sol_escape_char;
+ int password;
+ int port;
+ int active;
+ int retry;
+
+ uint32_t session_id;
+ uint32_t in_seq;
+ uint32_t out_seq;
+ uint32_t timeout;
+
+ struct sockaddr_in addr; /*old*/
+ socklen_t addrlen;
+
+ /*
+ * This struct holds state data specific to IPMI v2 / RMCP+ sessions
+ */
+ struct {
+ enum LANPLUS_SESSION_STATE session_state;
+
+ /* These are the algorithms agreed upon for the session */
+ uint8_t requested_auth_alg;
+ uint8_t requested_integrity_alg;
+ uint8_t requested_crypt_alg;
+ uint8_t auth_alg;
+ uint8_t integrity_alg;
+ uint8_t crypt_alg;
+ uint8_t max_priv_level;
+ uint8_t lookupbit;
+
+ uint32_t console_id;
+ uint32_t bmc_id;
+
+ /*
+ * Values required for RAKP mesages
+ */
+
+ /* Random number generated byt the console */
+ uint8_t console_rand[16];
+ /* Random number generated by the BMC */
+ uint8_t bmc_rand[16];
+
+ uint8_t bmc_guid[16];
+ uint8_t requested_role; /* As sent in the RAKP 1 message */
+ uint8_t rakp2_return_code;
+
+ uint8_t sik[EVP_MAX_MD_SIZE]; /* Session integrity key */
+ uint8_t kg[IPMI_KG_BUFFER_SIZE]; /* BMC key */
+ uint8_t k1[EVP_MAX_MD_SIZE]; /* Used for Integrity checking? */
+ uint8_t k2[EVP_MAX_MD_SIZE]; /* First 16 bytes used for AES */
+ uint8_t sik_len; /* length of sik */
+ uint8_t k1_len; /* length of k1 */
+ uint8_t k2_len; /* length of k2 */
+ } v2_data;
+
+
+ /*
+ * This data is specific to the Serial Over Lan session
+ */
+ struct {
+ uint16_t max_inbound_payload_size;
+ uint16_t max_outbound_payload_size;
+ uint16_t port;
+ uint8_t sequence_number;
+
+ /* This data describes the last SOL packet */
+ uint8_t last_received_sequence_number;
+ uint8_t last_received_byte_count;
+ void (*sol_input_handler)(struct ipmi_rs * rsp);
+ } sol_data;
+};
+
+struct ipmi_cmd {
+ int (*func)(struct ipmi_intf * intf, int argc, char ** argv);
+ const char * name;
+ const char * desc;
+};
+
+struct ipmi_intf_support {
+ const char * name;
+ int supported;
+};
+
+struct ipmi_intf {
+ char name[16];
+ char desc[128];
+ int fd;
+ int opened;
+ int abort;
+ int noanswer;
+
+ struct ipmi_session * session;
+ struct ipmi_oem_handle * oem;
+ struct ipmi_cmd * cmdlist;
+ uint32_t my_addr;
+ uint32_t target_addr;
+ uint8_t target_lun;
+ uint8_t target_channel;
+ uint32_t transit_addr;
+ uint8_t transit_channel;
+ uint8_t devnum;
+
+ int (*setup)(struct ipmi_intf * intf);
+ int (*open)(struct ipmi_intf * intf);
+ void (*close)(struct ipmi_intf * intf);
+ struct ipmi_rs *(*sendrecv)(struct ipmi_intf * intf, struct ipmi_rq * req);
+ int (*sendrsp)(struct ipmi_intf * intf, struct ipmi_rs * rsp);
+ struct ipmi_rs *(*recv_sol)(struct ipmi_intf * intf);
+ struct ipmi_rs *(*send_sol)(struct ipmi_intf * intf, struct ipmi_v2_payload * payload);
+ int (*keepalive)(struct ipmi_intf * intf);
+};
+#else
+
+#include "lanplus_defs.h"
+#endif
+
+struct ipmi_intf * ipmi_intf_load(char * name);
+void ipmi_intf_print(struct ipmi_intf_support * intflist);
+
+void ipmi_intf_session_set_hostname(struct ipmi_intf * intf, char * hostname);
+void ipmi_intf_session_set_username(struct ipmi_intf * intf, char * username);
+void ipmi_intf_session_set_password(struct ipmi_intf * intf, char * password);
+void ipmi_intf_session_set_privlvl(struct ipmi_intf * intf, uint8_t privlvl);
+void ipmi_intf_session_set_lookupbit(struct ipmi_intf * intf, uint8_t lookupbit);
+void ipmi_intf_session_set_cipher_suite_id(struct ipmi_intf * intf, uint8_t cipher_suite_id);
+void ipmi_intf_session_set_sol_escape_char(struct ipmi_intf * intf, char sol_escape_char);
+void ipmi_intf_session_set_kgkey(struct ipmi_intf * intf, char * kgkey);
+void ipmi_intf_session_set_port(struct ipmi_intf * intf, int port);
+void ipmi_intf_session_set_authtype(struct ipmi_intf * intf, uint8_t authtype);
+void ipmi_intf_session_set_timeout(struct ipmi_intf * intf, uint32_t timeout);
+void ipmi_intf_session_set_retry(struct ipmi_intf * intf, int retry);
+void ipmi_cleanup(struct ipmi_intf * intf);
+
+#endif /* IPMI_INTF_H */
diff --git a/lib/lanplus/inc/ipmitool/ipmi_isol.h b/lib/lanplus/inc/ipmitool/ipmi_isol.h
new file mode 100644
index 0000000..6a41b07
--- /dev/null
+++ b/lib/lanplus/inc/ipmitool/ipmi_isol.h
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+#ifndef IPMI_ISOL_H
+#define IPMI_ISOL_H
+
+#include <ipmitool/ipmi.h>
+
+#define ACTIVATE_ISOL 0x01
+#define SET_ISOL_CONFIG 0x03
+#define GET_ISOL_CONFIG 0x04
+
+#define ISOL_ENABLE_PARAM 0x01
+#define ISOL_AUTHENTICATION_PARAM 0x02
+#define ISOL_ENABLE_FLAG 0x01
+#define ISOL_PRIVILEGE_LEVEL_USER 0x02
+#define ISOL_BAUD_RATE_PARAM 0x05
+#define ISOL_BAUD_RATE_9600 0x06
+#define ISOL_BAUD_RATE_19200 0x07
+#define ISOL_BAUD_RATE_38400 0x08
+#define ISOL_BAUD_RATE_57600 0x09
+#define ISOL_BAUD_RATE_115200 0x0A
+#define ISOL_PREFERRED_BAUD_RATE 0x07
+
+int ipmi_isol_main(struct ipmi_intf *, int, char **);
+
+#endif /* IPMI_SOL_H */
diff --git a/lib/lanplus/inc/ipmitool/ipmi_kontronoem.h b/lib/lanplus/inc/ipmitool/ipmi_kontronoem.h
new file mode 100644
index 0000000..083e546
--- /dev/null
+++ b/lib/lanplus/inc/ipmitool/ipmi_kontronoem.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2004 Kontron Canada, Inc. All Rights Reserved.
+ *
+ * Base on code from
+ * 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.
+ */
+
+#ifndef IPMI_KONTRONOEM_H
+#define IPMI_KONTRONOEM_H
+
+#ifdef WIN32
+#include <inttypes-win.h>
+#else
+#include <inttypes.h>
+#endif
+#include <ipmitool/ipmi.h>
+
+
+int ipmi_kontronoem_main(struct ipmi_intf *, int, char **);
+
+#endif /* IPMI_KONTRONOEM_H */
diff --git a/lib/lanplus/inc/ipmitool/ipmi_lanp.h b/lib/lanplus/inc/ipmitool/ipmi_lanp.h
new file mode 100644
index 0000000..1aaae5e
--- /dev/null
+++ b/lib/lanplus/inc/ipmitool/ipmi_lanp.h
@@ -0,0 +1,132 @@
+/*
+ * 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.
+ */
+
+#ifndef IPMI_LANP_H
+#define IPMI_LANP_H
+
+#include <ipmitool/ipmi.h>
+
+#define IPMI_LAN_SET_CONFIG 0x01
+#define IPMI_LAN_GET_CONFIG 0x02
+#define IPMI_LAN_SUSPEND_ARP 0x03
+# define IPMI_LAN_SUSPEND_ARP_RESP (2)
+# define IPMI_LAN_SUSPEND_ARP_GRAT (1)
+#define IPMI_LAN_GET_STAT 0x04
+
+#define IPMI_CHANNEL_NUMBER_MAX 0xe
+
+#define IPMI_LANP_TIMEOUT 3
+#define IPMI_LANP_RETRIES 10
+#define IPMI_LANP_WRITE_UNLOCK 0
+#define IPMI_LANP_WRITE_LOCK 1
+#define IPMI_LANP_WRITE_COMMIT 2
+
+enum {
+ IPMI_LANP_SET_IN_PROGRESS,
+ IPMI_LANP_AUTH_TYPE,
+ IPMI_LANP_AUTH_TYPE_ENABLE,
+ IPMI_LANP_IP_ADDR,
+ IPMI_LANP_IP_ADDR_SRC,
+ IPMI_LANP_MAC_ADDR, /* 5 */
+ IPMI_LANP_SUBNET_MASK,
+ IPMI_LANP_IP_HEADER,
+ IPMI_LANP_PRI_RMCP_PORT,
+ IPMI_LANP_SEC_RMCP_PORT,
+ IPMI_LANP_BMC_ARP, /* 10 */
+ IPMI_LANP_GRAT_ARP,
+ IPMI_LANP_DEF_GATEWAY_IP,
+ IPMI_LANP_DEF_GATEWAY_MAC,
+ IPMI_LANP_BAK_GATEWAY_IP,
+ IPMI_LANP_BAK_GATEWAY_MAC, /* 15 */
+ IPMI_LANP_SNMP_STRING,
+ IPMI_LANP_NUM_DEST,
+ IPMI_LANP_DEST_TYPE,
+ IPMI_LANP_DEST_ADDR,
+ IPMI_LANP_VLAN_ID, /* 20 */
+ IPMI_LANP_VLAN_PRIORITY,
+ IPMI_LANP_RMCP_CIPHER_SUPPORT,
+ IPMI_LANP_RMCP_CIPHERS,
+ IPMI_LANP_RMCP_PRIV_LEVELS,
+ IPMI_LANP_OEM_ALERT_STRING=96,
+ IPMI_LANP_ALERT_RETRY=97,
+ IPMI_LANP_UTC_OFFSET=98,
+ IPMI_LANP_DHCP_SERVER_IP=192,
+ IPMI_LANP_DHCP_SERVER_MAC=193,
+ IPMI_LANP_DHCP_ENABLE=194,
+ IPMI_LANP_CHAN_ACCESS_MODE=201,
+};
+
+static struct lan_param {
+ int cmd;
+ int size;
+ char desc[24];
+ uint8_t * data;
+ int data_len;
+} ipmi_lan_params[] __attribute__((unused)) = {
+ { IPMI_LANP_SET_IN_PROGRESS, 1, "Set in Progress" },
+ { IPMI_LANP_AUTH_TYPE, 1, "Auth Type Support" },
+ { IPMI_LANP_AUTH_TYPE_ENABLE, 5, "Auth Type Enable" },
+ { IPMI_LANP_IP_ADDR, 4, "IP Address" },
+ { IPMI_LANP_IP_ADDR_SRC, 1, "IP Address Source" },
+ { IPMI_LANP_MAC_ADDR, 6, "MAC Address" }, /* 5 */
+ { IPMI_LANP_SUBNET_MASK, 4, "Subnet Mask" },
+ { IPMI_LANP_IP_HEADER, 3, "IP Header" },
+ { IPMI_LANP_PRI_RMCP_PORT, 2, "Primary RMCP Port" },
+ { IPMI_LANP_SEC_RMCP_PORT, 2, "Secondary RMCP Port" },
+ { IPMI_LANP_BMC_ARP, 1, "BMC ARP Control" }, /* 10 */
+ { IPMI_LANP_GRAT_ARP, 1, "Gratituous ARP Intrvl" },
+ { IPMI_LANP_DEF_GATEWAY_IP, 4, "Default Gateway IP" },
+ { IPMI_LANP_DEF_GATEWAY_MAC, 6, "Default Gateway MAC" },
+ { IPMI_LANP_BAK_GATEWAY_IP, 4, "Backup Gateway IP" },
+ { IPMI_LANP_BAK_GATEWAY_MAC, 6, "Backup Gateway MAC" }, /* 15 */
+ { IPMI_LANP_SNMP_STRING, 18, "SNMP Community String" },
+ { IPMI_LANP_NUM_DEST, 1, "Number of Destinations"},
+ { IPMI_LANP_DEST_TYPE, 4, "Destination Type" },
+ { IPMI_LANP_DEST_ADDR, 13, "Destination Addresses" },
+ { IPMI_LANP_VLAN_ID, 2, "802.1q VLAN ID" }, /* 20 */
+ { IPMI_LANP_VLAN_PRIORITY, 1, "802.1q VLAN Priority" },
+ { IPMI_LANP_RMCP_CIPHER_SUPPORT,1, "RMCP+ Cipher Suite Count" },
+ { IPMI_LANP_RMCP_CIPHERS, 16, "RMCP+ Cipher Suites" },
+ { IPMI_LANP_RMCP_PRIV_LEVELS, 9, "Cipher Suite Priv Max" },
+ { IPMI_LANP_OEM_ALERT_STRING, 28, "OEM Alert String" }, /* 25 */
+ { IPMI_LANP_ALERT_RETRY, 1, "Alert Retry Algorithm" },
+ { IPMI_LANP_UTC_OFFSET, 3, "UTC Offset" },
+ { IPMI_LANP_DHCP_SERVER_IP, 4, "DHCP Server IP" },
+ { IPMI_LANP_DHCP_SERVER_MAC, 6, "DHDP Server MAC" },
+ { IPMI_LANP_DHCP_ENABLE, 1, "DHCP Enable" }, /* 30 */
+ { IPMI_LANP_CHAN_ACCESS_MODE, 2, "Channel Access Mode" },
+ { -1 }
+};
+
+int ipmi_lanp_main(struct ipmi_intf *, int, char **);
+
+#endif /*IPMI_LANP_H*/
diff --git a/lib/lanplus/inc/ipmitool/ipmi_main.h b/lib/lanplus/inc/ipmitool/ipmi_main.h
new file mode 100644
index 0000000..e32360a
--- /dev/null
+++ b/lib/lanplus/inc/ipmitool/ipmi_main.h
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+#ifndef IPMI_MAIN_H
+#define IPMI_MAIN_H
+
+#include <ipmitool/ipmi_intf.h>
+
+int ipmi_main(int argc, char ** argv, struct ipmi_cmd * cmdlist, struct ipmi_intf_support * intflist);
+void ipmi_cmd_print(struct ipmi_cmd * cmdlist);
+int ipmi_cmd_run(struct ipmi_intf * intf, char * name, int argc, char ** argv);
+
+#endif /* IPMI_MAIN_H */
diff --git a/lib/lanplus/inc/ipmitool/ipmi_mc.h b/lib/lanplus/inc/ipmitool/ipmi_mc.h
new file mode 100644
index 0000000..601f40e
--- /dev/null
+++ b/lib/lanplus/inc/ipmitool/ipmi_mc.h
@@ -0,0 +1,103 @@
+/*
+ * 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.
+ */
+
+#ifndef IPMI_MC_H
+#define IPMI_MC_H
+
+#include <ipmitool/ipmi.h>
+
+#define BMC_GET_DEVICE_ID 0x01
+#define BMC_COLD_RESET 0x02
+#define BMC_WARM_RESET 0x03
+#define BMC_GET_SELF_TEST 0x04
+#define BMC_SET_GLOBAL_ENABLES 0x2e
+#define BMC_GET_GLOBAL_ENABLES 0x2f
+#define BMC_GET_GUID 0x37
+
+int ipmi_mc_main(struct ipmi_intf *, int, char **);
+
+/*
+ * Response data from IPM Get Device ID Command (IPMI rev 1.5, section 17.1)
+ * The following really apply to any IPM device, not just BMCs...
+ */
+struct ipm_devid_rsp {
+ uint8_t device_id;
+ uint8_t device_revision;
+ uint8_t fw_rev1;
+ uint8_t fw_rev2;
+ uint8_t ipmi_version;
+ uint8_t adtl_device_support;
+ uint8_t manufacturer_id[3];
+ uint8_t product_id[2];
+ uint8_t aux_fw_rev[4];
+} __attribute__ ((packed));
+
+#define IPM_DEV_DEVICE_ID_SDR_MASK (0x80) /* 1 = provides SDRs */
+#define IPM_DEV_DEVICE_ID_REV_MASK (0x07) /* BCD-enoded */
+
+#define IPM_DEV_FWREV1_AVAIL_MASK (0x80) /* 0 = normal operation */
+#define IPM_DEV_FWREV1_MAJOR_MASK (0x3f) /* Major rev, BCD-encoded */
+
+#define IPM_DEV_IPMI_VER_MAJOR_MASK (0x0F) /* Major rev, BCD-encoded */
+#define IPM_DEV_IPMI_VER_MINOR_MASK (0xF0) /* Minor rev, BCD-encoded */
+#define IPM_DEV_IPMI_VER_MINOR_SHIFT (4) /* Minor rev shift */
+#define IPM_DEV_IPMI_VERSION_MAJOR(x) \
+ (x & IPM_DEV_IPMI_VER_MAJOR_MASK)
+#define IPM_DEV_IPMI_VERSION_MINOR(x) \
+ ((x & IPM_DEV_IPMI_VER_MINOR_MASK) >> IPM_DEV_IPMI_VER_MINOR_SHIFT)
+
+#define IPM_DEV_MANUFACTURER_ID(x) \
+ ((uint32_t) ((x[2] & 0x0F) << 16 | x[1] << 8 | x[0]))
+
+#define IPM_DEV_ADTL_SUPPORT_BITS (8)
+
+struct ipm_selftest_rsp {
+ unsigned char code;
+ unsigned char test;
+} __attribute__ ((packed));
+
+#define IPM_SFT_CODE_OK 0x55
+#define IPM_SFT_CODE_NOT_IMPLEMENTED 0x56
+#define IPM_SFT_CODE_DEV_CORRUPTED 0x57
+#define IPM_SFT_CODE_FATAL_ERROR 0x58
+#define IPM_SFT_CODE_RESERVED 0xff
+
+#define IPM_SELFTEST_SEL_ERROR 0x80
+#define IPM_SELFTEST_SDR_ERROR 0x40
+#define IPM_SELFTEST_FRU_ERROR 0x20
+#define IPM_SELFTEST_IPMB_ERROR 0x10
+#define IPM_SELFTEST_SDRR_EMPTY 0x08
+#define IPM_SELFTEST_INTERNAL_USE 0x04
+#define IPM_SELFTEST_FW_BOOTBLOCK 0x02
+#define IPM_SELFTEST_FW_CORRUPTED 0x01
+
+#endif /*IPMI_MC_H */
diff --git a/lib/lanplus/inc/ipmitool/ipmi_oem.h b/lib/lanplus/inc/ipmitool/ipmi_oem.h
new file mode 100644
index 0000000..ad22fde
--- /dev/null
+++ b/lib/lanplus/inc/ipmitool/ipmi_oem.h
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+#ifndef IPMI_OEM_H
+#define IPMI_OEM_H
+
+#include <ipmitool/ipmi.h>
+
+/* oem handler, see lib/ipmi_oem.c */
+struct ipmi_oem_handle {
+ const char * name;
+ const char * desc;
+ int (*setup)(struct ipmi_intf * intf);
+};
+
+void ipmi_oem_print(void);
+int ipmi_oem_setup(struct ipmi_intf * intf, char * oemtype);
+int ipmi_oem_active(struct ipmi_intf * intf, const char * oemtype);
+
+#endif /*IPMI_OEM_H*/
diff --git a/lib/lanplus/inc/ipmitool/ipmi_pef.h b/lib/lanplus/inc/ipmitool/ipmi_pef.h
new file mode 100644
index 0000000..904a2ac
--- /dev/null
+++ b/lib/lanplus/inc/ipmitool/ipmi_pef.h
@@ -0,0 +1,784 @@
+/*
+ * Copyright (c) 2004 Dell Computers. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Dell Computers, or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind.
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
+ * DELL COMPUTERS ("DELL") AND ITS LICENSORS SHALL NOT BE LIABLE
+ * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
+ * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
+ * DELL OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
+ * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
+ * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
+ * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
+ * EVEN IF DELL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#ifndef IPMI_PEF_H
+#define IPMI_PEF_H
+
+#include <ipmitool/ipmi.h>
+
+/* PEF */
+
+struct pef_capabilities { /* "get pef capabilities" response */
+ uint8_t version;
+ uint8_t actions; /* mapped by PEF_ACTION_xxx */
+ uint8_t tblsize;
+};
+
+typedef enum {
+ P_TRUE,
+ P_SUPP,
+ P_ACTV,
+ P_ABLE,
+} flg_e;
+
+struct pef_table_entry {
+#define PEF_CONFIG_ENABLED 0x80
+#define PEF_CONFIG_PRECONFIGURED 0x40
+ uint8_t config;
+#define PEF_ACTION_DIAGNOSTIC_INTERRUPT 0x20
+#define PEF_ACTION_OEM 0x10
+#define PEF_ACTION_POWER_CYCLE 0x08
+#define PEF_ACTION_RESET 0x04
+#define PEF_ACTION_POWER_DOWN 0x02
+#define PEF_ACTION_ALERT 0x01
+ uint8_t action;
+#define PEF_POLICY_NUMBER_MASK 0x0f
+ uint8_t policy_number;
+#define PEF_SEVERITY_NON_RECOVERABLE 0x20
+#define PEF_SEVERITY_CRITICAL 0x10
+#define PEF_SEVERITY_WARNING 0x08
+#define PEF_SEVERITY_OK 0x04
+#define PEF_SEVERITY_INFORMATION 0x02
+#define PEF_SEVERITY_MONITOR 0x01
+ uint8_t severity;
+ uint8_t generator_ID_addr;
+ uint8_t generator_ID_lun;
+ uint8_t sensor_type;
+#define PEF_SENSOR_NUMBER_MATCH_ANY 0xff
+ uint8_t sensor_number;
+#define PEF_EVENT_TRIGGER_UNSPECIFIED 0x0
+#define PEF_EVENT_TRIGGER_THRESHOLD 0x1
+#define PEF_EVENT_TRIGGER_SENSOR_SPECIFIC 0x6f
+#define PEF_EVENT_TRIGGER_MATCH_ANY 0xff
+ uint8_t event_trigger;
+ uint8_t event_data_1_offset_mask[2];
+ uint8_t event_data_1_AND_mask;
+ uint8_t event_data_1_compare_1;
+ uint8_t event_data_1_compare_2;
+ uint8_t event_data_2_AND_mask;
+ uint8_t event_data_2_compare_1;
+ uint8_t event_data_2_compare_2;
+ uint8_t event_data_3_AND_mask;
+ uint8_t event_data_3_compare_1;
+ uint8_t event_data_3_compare_2;
+} __attribute__ ((packed));
+
+struct desc_map { /* maps a description to a value/mask */
+ const char *desc;
+ uint32_t mask;
+};
+
+struct bit_desc_map { /* description text container */
+#define BIT_DESC_MAP_LIST 0x1 /* index-based text array */
+#define BIT_DESC_MAP_ANY 0x2 /* bitwise, but only print 1st one */
+#define BIT_DESC_MAP_ALL 0x3 /* bitwise, print them all */
+ uint32_t desc_map_type;
+ struct desc_map desc_maps[128];
+};
+
+static struct bit_desc_map
+pef_b2s_actions __attribute__((unused)) = {
+BIT_DESC_MAP_ALL,
+{ {"Alert", PEF_ACTION_ALERT},
+ {"Power-off", PEF_ACTION_POWER_DOWN},
+ {"Reset", PEF_ACTION_RESET},
+ {"Power-cycle", PEF_ACTION_POWER_CYCLE},
+ {"OEM-defined", PEF_ACTION_OEM},
+ {"Diagnostic-interrupt", PEF_ACTION_DIAGNOSTIC_INTERRUPT},
+ {NULL}
+} };
+
+static struct bit_desc_map
+pef_b2s_severities __attribute__((unused)) = {
+BIT_DESC_MAP_ANY,
+{ {"Non-recoverable", PEF_SEVERITY_NON_RECOVERABLE},
+ {"Critical", PEF_SEVERITY_CRITICAL},
+ {"Warning", PEF_SEVERITY_WARNING},
+ {"OK", PEF_SEVERITY_OK},
+ {"Information", PEF_SEVERITY_INFORMATION},
+ {"Monitor", PEF_SEVERITY_MONITOR},
+ {NULL}
+} };
+
+static struct bit_desc_map
+pef_b2s_sensortypes __attribute__((unused)) = {
+BIT_DESC_MAP_LIST,
+{ {"Any", 255},
+ {"Temperature", 1},
+ {"Voltage", 2},
+ {"Current", 3},
+ {"Fan", 4},
+ {"Chassis Intrusion", 5},
+ {"Platform security breach", 6},
+ {"Processor", 7},
+ {"Power supply", 8},
+ {"Power Unit", 9},
+ {"Cooling device", 10},
+ {"Other (units-based)", 11},
+ {"Memory", 12},
+ {"Drive Slot", 13},
+ {"POST memory resize", 14},
+ {"POST error", 15},
+ {"Logging disabled", 16},
+ {"Watchdog 1", 17},
+ {"System event", 18},
+ {"Critical Interrupt", 19},
+ {"Button", 20},
+ {"Module/board", 21},
+ {"uController/coprocessor", 22},
+ {"Add-in card", 23},
+ {"Chassis", 24},
+ {"Chipset", 25},
+ {"Other (FRU)", 26},
+ {"Cable/interconnect", 27},
+ {"Terminator", 28},
+ {"System boot", 29},
+ {"Boot error", 30},
+ {"OS boot", 31},
+ {"OS critical stop", 32},
+ {"Slot/connector", 33},
+ {"ACPI power state", 34},
+ {"Watchdog 2", 35},
+ {"Platform alert", 36},
+ {"Entity presence", 37},
+ {"Monitor ASIC/IC", 38},
+ {"LAN", 39},
+ {"Management subsytem health",40},
+ {"Battery", 41},
+ {NULL}
+} };
+
+static struct bit_desc_map
+pef_b2s_gentype_1 = {
+BIT_DESC_MAP_LIST,
+{ {"<LNC", 0}, /* '<' : getting worse */
+ {">LNC", 1}, /* '>' : getting better */
+ {"<LC", 2},
+ {">LC", 3},
+ {"<LNR", 4},
+ {">LNR", 5},
+ {">UNC", 6},
+ {"<UNC", 7},
+ {">UC", 8},
+ {"<UC", 9},
+ {">UNR", 10},
+ {"<UNR", 11},
+ {NULL}
+} };
+
+static struct bit_desc_map
+pef_b2s_gentype_2 = {
+BIT_DESC_MAP_LIST,
+{ {"transition to idle", 0},
+ {"transition to active", 1},
+ {"transition to busy", 2},
+ {NULL}
+} };
+
+static struct bit_desc_map
+pef_b2s_gentype_3 = {
+BIT_DESC_MAP_LIST,
+{ {"state deasserted", 0},
+ {"state asserted", 1},
+ {NULL}
+} };
+
+static struct bit_desc_map
+pef_b2s_gentype_4 = {
+BIT_DESC_MAP_LIST,
+{ {"predictive failure deasserted", 0},
+ {"predictive failure asserted", 1},
+ {NULL}
+} };
+
+static struct bit_desc_map
+pef_b2s_gentype_5 = {
+BIT_DESC_MAP_LIST,
+{ {"limit not exceeded", 0},
+ {"limit exceeded", 1},
+ {NULL}
+} };
+
+static struct bit_desc_map
+pef_b2s_gentype_6 = {
+BIT_DESC_MAP_LIST,
+{ {"performance met", 0},
+ {"performance lags", 1},
+ {NULL}
+} };
+
+static struct bit_desc_map
+pef_b2s_gentype_7 = {
+BIT_DESC_MAP_LIST,
+{ {"ok", 0},
+ {"<warn", 1}, /* '<' : getting worse */
+ {"<fail", 2},
+ {"<dead", 3},
+ {">warn", 4}, /* '>' : getting better */
+ {">fail", 5},
+ {"dead", 6},
+ {"monitor", 7},
+ {"informational", 8},
+ {NULL}
+} };
+
+static struct bit_desc_map
+pef_b2s_gentype_8 = {
+BIT_DESC_MAP_LIST,
+{ {"device removed/absent", 0},
+ {"device inserted/present", 1},
+ {NULL}
+} };
+
+static struct bit_desc_map
+pef_b2s_gentype_9 = {
+BIT_DESC_MAP_LIST,
+{ {"device disabled", 0},
+ {"device enabled", 1},
+ {NULL}
+} };
+
+static struct bit_desc_map
+pef_b2s_gentype_10 = {
+BIT_DESC_MAP_LIST,
+{ {"transition to running", 0},
+ {"transition to in test", 1},
+ {"transition to power off", 2},
+ {"transition to online", 3},
+ {"transition to offline", 4},
+ {"transition to off duty", 5},
+ {"transition to degraded", 6},
+ {"transition to power save", 7},
+ {"install error", 8},
+ {NULL}
+} };
+
+static struct bit_desc_map
+pef_b2s_gentype_11 = {
+BIT_DESC_MAP_LIST,
+{ {"fully redundant", 0},
+ {"redundancy lost", 1},
+ {"redundancy degraded", 2},
+ {"<non-redundant/sufficient", 3}, /* '<' : getting worse */
+ {">non-redundant/sufficient", 4}, /* '>' : getting better */
+ {"non-redundant/insufficient", 5},
+ {"<redundancy degraded", 6},
+ {">redundancy degraded", 7},
+ {NULL}
+} };
+
+static struct bit_desc_map
+pef_b2s_gentype_12 = {
+BIT_DESC_MAP_LIST,
+{ {"D0 power state", 0},
+ {"D1 power state", 1},
+ {"D2 power state", 2},
+ {"D3 power state", 3},
+ {NULL}
+} };
+
+static struct bit_desc_map *
+pef_b2s_generic_ER[] __attribute__((unused)) = {
+ &pef_b2s_gentype_1,
+ &pef_b2s_gentype_2,
+ &pef_b2s_gentype_3,
+ &pef_b2s_gentype_4,
+ &pef_b2s_gentype_5,
+ &pef_b2s_gentype_6,
+ &pef_b2s_gentype_7,
+ &pef_b2s_gentype_8,
+ &pef_b2s_gentype_9,
+ &pef_b2s_gentype_10,
+ &pef_b2s_gentype_11,
+ &pef_b2s_gentype_12,
+};
+#define PEF_B2S_GENERIC_ER_ENTRIES \
+ (sizeof(pef_b2s_generic_ER) / sizeof(pef_b2s_generic_ER[0]))
+
+struct pef_policy_entry {
+#define PEF_POLICY_ID_MASK 0xf0
+#define PEF_POLICY_ID_SHIFT 4
+#define PEF_POLICY_ENABLED 0x08
+#define PEF_POLICY_FLAGS_MASK 0x07
+#define PEF_POLICY_FLAGS_MATCH_ALWAYS 0
+#define PEF_POLICY_FLAGS_PREV_OK_SKIP 1
+#define PEF_POLICY_FLAGS_PREV_OK_NEXT_POLICY_SET 2
+#define PEF_POLICY_FLAGS_PREV_OK_NEXT_CHANNEL_IN_SET 3
+#define PEF_POLICY_FLAGS_PREV_OK_NEXT_DESTINATION_IN_SET 4
+ uint8_t policy;
+#define PEF_POLICY_CHANNEL_MASK 0xf0
+#define PEF_POLICY_CHANNEL_SHIFT 4
+#define PEF_POLICY_DESTINATION_MASK 0x0f
+ uint8_t chan_dest;
+#define PEF_POLICY_EVENT_SPECIFIC 0x80
+ uint8_t alert_string_key;
+} __attribute__ ((packed));
+
+static struct bit_desc_map
+pef_b2s_policies __attribute__((unused)) = {
+BIT_DESC_MAP_LIST,
+{ {"Match-always", PEF_POLICY_FLAGS_MATCH_ALWAYS},
+ {"Try-next-entry", PEF_POLICY_FLAGS_PREV_OK_SKIP},
+ {"Try-next-set", PEF_POLICY_FLAGS_PREV_OK_NEXT_POLICY_SET},
+ {"Try-next-channel", PEF_POLICY_FLAGS_PREV_OK_NEXT_CHANNEL_IN_SET},
+ {"Try-next-destination", PEF_POLICY_FLAGS_PREV_OK_NEXT_DESTINATION_IN_SET},
+ {NULL}
+} };
+
+static struct bit_desc_map
+pef_b2s_ch_medium __attribute__((unused)) = {
+#define PEF_CH_MEDIUM_TYPE_IPMB 1
+#define PEF_CH_MEDIUM_TYPE_ICMB_10 2
+#define PEF_CH_MEDIUM_TYPE_ICMB_09 3
+#define PEF_CH_MEDIUM_TYPE_LAN 4
+#define PEF_CH_MEDIUM_TYPE_SERIAL 5
+#define PEF_CH_MEDIUM_TYPE_XLAN 6
+#define PEF_CH_MEDIUM_TYPE_PCI_SMBUS 7
+#define PEF_CH_MEDIUM_TYPE_SMBUS_V1X 8
+#define PEF_CH_MEDIUM_TYPE_SMBUS_V2X 9
+#define PEF_CH_MEDIUM_TYPE_USB_V1X 10
+#define PEF_CH_MEDIUM_TYPE_USB_V2X 11
+#define PEF_CH_MEDIUM_TYPE_SYSTEM 12
+BIT_DESC_MAP_LIST,
+{ {"IPMB (I2C)", PEF_CH_MEDIUM_TYPE_IPMB},
+ {"ICMB v1.0", PEF_CH_MEDIUM_TYPE_ICMB_10},
+ {"ICMB v0.9", PEF_CH_MEDIUM_TYPE_ICMB_09},
+ {"802.3 LAN", PEF_CH_MEDIUM_TYPE_LAN},
+ {"Serial/Modem (RS-232)", PEF_CH_MEDIUM_TYPE_SERIAL},
+ {"Other LAN", PEF_CH_MEDIUM_TYPE_XLAN},
+ {"PCI SMBus", PEF_CH_MEDIUM_TYPE_PCI_SMBUS},
+ {"SMBus v1.0/1.1", PEF_CH_MEDIUM_TYPE_SMBUS_V1X},
+ {"SMBus v2.0", PEF_CH_MEDIUM_TYPE_SMBUS_V2X},
+ {"USB 1.x", PEF_CH_MEDIUM_TYPE_USB_V1X},
+ {"USB 2.x", PEF_CH_MEDIUM_TYPE_USB_V2X},
+ {"System I/F (KCS,SMIC,BT)", PEF_CH_MEDIUM_TYPE_SYSTEM},
+ {NULL}
+} };
+
+struct pef_cfgparm_selector {
+#define PEF_CFGPARM_ID_REVISION_ONLY_MASK 0x80
+#define PEF_CFGPARM_ID_SET_IN_PROGRESS 0
+#define PEF_CFGPARM_ID_PEF_CONTROL 1
+#define PEF_CFGPARM_ID_PEF_ACTION 2
+#define PEF_CFGPARM_ID_PEF_STARTUP_DELAY 3
+#define PEF_CFGPARM_ID_PEF_ALERT_STARTUP_DELAY 4
+#define PEF_CFGPARM_ID_PEF_FILTER_TABLE_SIZE 5
+#define PEF_CFGPARM_ID_PEF_FILTER_TABLE_ENTRY 6
+#define PEF_CFGPARM_ID_PEF_FILTER_TABLE_DATA_1 7
+#define PEF_CFGPARM_ID_PEF_ALERT_POLICY_TABLE_SIZE 8
+#define PEF_CFGPARM_ID_PEF_ALERT_POLICY_TABLE_ENTRY 9
+#define PEF_CFGPARM_ID_SYSTEM_GUID 10
+#define PEF_CFGPARM_ID_PEF_ALERT_STRING_TABLE_SIZE 11
+#define PEF_CFGPARM_ID_PEF_ALERT_STRING_KEY 12
+#define PEF_CFGPARM_ID_PEF_ALERT_STRING_TABLE_ENTRY 13
+ uint8_t id;
+ uint8_t set;
+ uint8_t block;
+} __attribute__ ((packed));
+
+struct pef_cfgparm_set_in_progress {
+#define PEF_SET_IN_PROGRESS_COMMIT_WRITE 0x02
+#define PEF_SET_IN_PROGRESS 0x01
+ uint8_t data1;
+} __attribute__ ((packed));
+
+struct pef_cfgparm_control {
+#define PEF_CONTROL_ENABLE_ALERT_STARTUP_DELAY 0x08
+#define PEF_CONTROL_ENABLE_STARTUP_DELAY 0x04
+#define PEF_CONTROL_ENABLE_EVENT_MESSAGES 0x02
+#define PEF_CONTROL_ENABLE 0x01
+ uint8_t data1;
+} __attribute__ ((packed));
+
+static struct bit_desc_map
+pef_b2s_control __attribute__((unused)) = {
+BIT_DESC_MAP_ALL,
+{ {"PEF", PEF_CONTROL_ENABLE},
+ {"PEF event messages", PEF_CONTROL_ENABLE_EVENT_MESSAGES},
+ {"PEF startup delay", PEF_CONTROL_ENABLE_STARTUP_DELAY},
+ {"Alert startup delay", PEF_CONTROL_ENABLE_ALERT_STARTUP_DELAY},
+ {NULL}
+} };
+
+struct pef_cfgparm_action {
+#define PEF_ACTION_ENABLE_DIAGNOSTIC_INTERRUPT 0x20
+#define PEF_ACTION_ENABLE_OEM 0x10
+#define PEF_ACTION_ENABLE_POWER_CYCLE 0x08
+#define PEF_ACTION_ENABLE_RESET 0x04
+#define PEF_ACTION_ENABLE_POWER_DOWN 0x02
+#define PEF_ACTION_ENABLE_ALERT 0x01
+ uint8_t data1;
+} __attribute__ ((packed));
+
+struct pef_cfgparm_startup_delay {
+ uint8_t data1;
+} __attribute__ ((packed));
+
+struct pef_cfgparm_alert_startup_delay {
+ uint8_t data1;
+} __attribute__ ((packed));
+
+struct pef_cfgparm_filter_table_size {
+#define PEF_FILTER_TABLE_SIZE_MASK 0x7f
+ uint8_t data1;
+} __attribute__ ((packed));
+
+struct pef_cfgparm_filter_table_entry {
+#define PEF_FILTER_TABLE_ID_MASK 0x7f
+ uint8_t data1;
+ struct pef_table_entry entry;
+} __attribute__ ((packed));
+
+struct pef_cfgparm_filter_table_data_1 {
+ uint8_t data1;
+ uint8_t data2;
+} __attribute__ ((packed));
+
+struct pef_cfgparm_policy_table_size {
+#define PEF_POLICY_TABLE_SIZE_MASK 0x7f
+ uint8_t data1;
+} __attribute__ ((packed));
+
+struct pef_cfgparm_policy_table_entry {
+#define PEF_POLICY_TABLE_ID_MASK 0x7f
+ uint8_t data1;
+ struct pef_policy_entry entry;
+} __attribute__ ((packed));
+
+struct pef_cfgparm_system_guid {
+#define PEF_SYSTEM_GUID_USED_IN_PET 0x01
+ uint8_t data1;
+ uint8_t guid[16];
+} __attribute__ ((packed));
+
+struct pef_cfgparm_alert_string_table_size {
+#define PEF_ALERT_STRING_TABLE_SIZE_MASK 0x7f
+ uint8_t data1;
+} __attribute__ ((packed));
+
+struct pef_cfgparm_alert_string_keys {
+#define PEF_ALERT_STRING_ID_MASK 0x7f
+ uint8_t data1;
+#define PEF_EVENT_FILTER_ID_MASK 0x7f
+ uint8_t data2;
+#define PEF_ALERT_STRING_SET_ID_MASK 0x7f
+ uint8_t data3;
+} __attribute__ ((packed));
+
+struct pef_cfgparm_alert_string_table_entry {
+ uint8_t id;
+ uint8_t blockno;
+ uint8_t block[16];
+} __attribute__ ((packed));
+
+/* PEF - LAN */
+
+struct pef_lan_cfgparm_selector {
+#define PEF_LAN_CFGPARM_CH_REVISION_ONLY_MASK 0x80
+#define PEF_LAN_CFGPARM_CH_MASK 0x0f
+#define PEF_LAN_CFGPARM_ID_PET_COMMUNITY 16
+#define PEF_LAN_CFGPARM_ID_DEST_COUNT 17
+#define PEF_LAN_CFGPARM_ID_DESTTYPE 18
+#define PEF_LAN_CFGPARM_ID_DESTADDR 19
+ uint8_t ch;
+ uint8_t id;
+ uint8_t set;
+ uint8_t block;
+} __attribute__ ((packed));
+
+struct pef_lan_cfgparm_dest_size {
+#define PEF_LAN_DEST_TABLE_SIZE_MASK 0x0f
+ uint8_t data1;
+} __attribute__ ((packed));
+
+struct pef_lan_cfgparm_dest_type {
+#define PEF_LAN_DEST_TYPE_ID_MASK 0x0f
+ uint8_t dest;
+#define PEF_LAN_DEST_TYPE_ACK 0x80
+#define PEF_LAN_DEST_TYPE_MASK 0x07
+#define PEF_LAN_DEST_TYPE_PET 0
+#define PEF_LAN_DEST_TYPE_OEM_1 6
+#define PEF_LAN_DEST_TYPE_OEM_2 7
+ uint8_t dest_type;
+ uint8_t alert_timeout;
+#define PEF_LAN_RETRIES_MASK 0x07
+ uint8_t retries;
+} __attribute__ ((packed));
+
+static struct bit_desc_map
+pef_b2s_lan_desttype __attribute__((unused)) = {
+BIT_DESC_MAP_LIST,
+{ {"Acknowledged", PEF_LAN_DEST_TYPE_ACK},
+ {"PET", PEF_LAN_DEST_TYPE_PET},
+ {"OEM 1", PEF_LAN_DEST_TYPE_OEM_1},
+ {"OEM 2", PEF_LAN_DEST_TYPE_OEM_2},
+ {NULL}
+} };
+
+struct pef_lan_cfgparm_dest_info {
+#define PEF_LAN_DEST_MASK 0x0f
+ uint8_t dest;
+#define PEF_LAN_DEST_ADDRTYPE_MASK 0xf0
+#define PEF_LAN_DEST_ADDRTYPE_SHIFT 4
+#define PEF_LAN_DEST_ADDRTYPE_IPV4_MAC 0x00
+ uint8_t addr_type;
+#define PEF_LAN_DEST_GATEWAY_USE_BACKUP 0x01
+ uint8_t gateway;
+ uint8_t ip[4];
+ uint8_t mac[6];
+} __attribute__ ((packed));
+
+/* PEF - Serial/PPP */
+
+struct pef_serial_cfgparm_selector {
+#define PEF_SERIAL_CFGPARM_CH_REVISION_ONLY_MASK 0x80
+#define PEF_SERIAL_CFGPARM_CH_MASK 0x0f
+#define PEF_SERIAL_CFGPARM_ID_DEST_COUNT 16
+#define PEF_SERIAL_CFGPARM_ID_DESTINFO 17
+#define PEF_SERIAL_CFGPARM_ID_DEST_DIAL_STRING_COUNT 20
+#define PEF_SERIAL_CFGPARM_ID_DEST_DIAL_STRING 21
+#define PEF_SERIAL_CFGPARM_ID_TAP_ACCT_COUNT 24
+#define PEF_SERIAL_CFGPARM_ID_TAP_ACCT_INFO 25
+#define PEF_SERIAL_CFGPARM_ID_TAP_ACCT_PAGER_STRING 27
+ uint8_t ch;
+ uint8_t id;
+ uint8_t set;
+ uint8_t block;
+} __attribute__ ((packed));
+
+struct pef_serial_cfgparm_dest_size {
+#define PEF_SERIAL_DEST_TABLE_SIZE_MASK 0x0f
+ uint8_t data1;
+} __attribute__ ((packed));
+
+struct pef_serial_cfgparm_dest_info {
+#define PEF_SERIAL_DEST_MASK 0x0f
+ uint8_t dest;
+#define PEF_SERIAL_DEST_TYPE_ACK 0x80
+#define PEF_SERIAL_DEST_TYPE_MASK 0x0f
+#define PEF_SERIAL_DEST_TYPE_DIAL 0
+#define PEF_SERIAL_DEST_TYPE_TAP 1
+#define PEF_SERIAL_DEST_TYPE_PPP 2
+#define PEF_SERIAL_DEST_TYPE_BASIC_CALLBACK 3
+#define PEF_SERIAL_DEST_TYPE_PPP_CALLBACK 4
+#define PEF_SERIAL_DEST_TYPE_OEM_1 14
+#define PEF_SERIAL_DEST_TYPE_OEM_2 15
+ uint8_t dest_type;
+ uint8_t alert_timeout;
+#define PEF_SERIAL_RETRIES_MASK 0x77
+#define PEF_SERIAL_RETRIES_POST_CONNECT_MASK 0x70
+#define PEF_SERIAL_RETRIES_PRE_CONNECT_MASK 0x07
+ uint8_t retries;
+#define PEF_SERIAL_DIALPAGE_STRING_ID_MASK 0xf0
+#define PEF_SERIAL_DIALPAGE_STRING_ID_SHIFT 4
+#define PEF_SERIAL_TAP_PAGE_SERVICE_ID_MASK 0x0f
+#define PEF_SERIAL_PPP_ACCT_IPADDR_ID_MASK 0xf0
+#define PEF_SERIAL_PPP_ACCT_IPADDR_ID_SHIFT 4
+#define PEF_SERIAL_PPP_ACCT_ID_MASK 0x0f
+#define PEF_SERIAL_CALLBACK_IPADDR_ID_MASK 0x0f
+#define PEF_SERIAL_CALLBACK_IPADDR_ID_SHIFT 4
+#define PEF_SERIAL_CALLBACK_ACCT_ID_MASK 0xf0
+ uint8_t data5;
+} __attribute__ ((packed));
+
+static struct bit_desc_map
+pef_b2s_serial_desttype __attribute__((unused)) = {
+BIT_DESC_MAP_LIST,
+{ {"Acknowledged", PEF_SERIAL_DEST_TYPE_ACK},
+ {"TAP page", PEF_SERIAL_DEST_TYPE_TAP},
+ {"PPP PET", PEF_SERIAL_DEST_TYPE_PPP},
+ {"Basic callback", PEF_SERIAL_DEST_TYPE_BASIC_CALLBACK},
+ {"PPP callback", PEF_SERIAL_DEST_TYPE_PPP_CALLBACK},
+ {"OEM 1", PEF_SERIAL_DEST_TYPE_OEM_1},
+ {"OEM 2", PEF_SERIAL_DEST_TYPE_OEM_2},
+ {NULL}
+} };
+
+struct pef_serial_cfgparm_dial_string_count {
+#define PEF_SERIAL_DIAL_STRING_COUNT_MASK 0x0f
+ uint8_t data1;
+} __attribute__ ((packed));
+
+struct pef_serial_cfgparm_dial_string {
+#define PEF_SERIAL_DIAL_STRING_MASK 0x0f
+ uint8_t data1;
+ uint8_t data2;
+ uint8_t data3;
+} __attribute__ ((packed));
+
+struct pef_serial_cfgparm_tap_acct_count {
+#define PEF_SERIAL_TAP_ACCT_COUNT_MASK 0x0f
+ uint8_t data1;
+} __attribute__ ((packed));
+
+struct pef_serial_cfgparm_tap_acct_info {
+ uint8_t data1;
+#define PEF_SERIAL_TAP_ACCT_INFO_DIAL_STRING_ID_MASK 0xf0
+#define PEF_SERIAL_TAP_ACCT_INFO_DIAL_STRING_ID_SHIFT 4
+#define PEF_SERIAL_TAP_ACCT_INFO_SVC_SETTINGS_ID_MASK 0x0f
+ uint8_t data2;
+} __attribute__ ((packed));
+
+struct pef_serial_cfgparm_tap_svc_settings {
+ uint8_t data1;
+#define PEF_SERIAL_TAP_CONFIRMATION_ACK_AFTER_ETX 0x0
+#define PEF_SERIAL_TAP_CONFIRMATION_211_ACK_AFTER_ETX 0x01
+#define PEF_SERIAL_TAP_CONFIRMATION_21X_ACK_AFTER_ETX 0x02
+ uint8_t confirmation_flags;
+ uint8_t service_type[3];
+ uint8_t escape_mask[4];
+ uint8_t timeout_parms[3];
+ uint8_t retry_parms[2];
+} __attribute__ ((packed));
+
+static struct bit_desc_map
+pef_b2s_tap_svc_confirm __attribute__((unused)) = {
+BIT_DESC_MAP_LIST,
+{ {"ACK", PEF_SERIAL_TAP_CONFIRMATION_ACK_AFTER_ETX},
+ {"211+ACK", PEF_SERIAL_TAP_CONFIRMATION_211_ACK_AFTER_ETX},
+ {"{211|213}+ACK", PEF_SERIAL_TAP_CONFIRMATION_21X_ACK_AFTER_ETX},
+ {NULL}
+} };
+
+#if 0 /* FYI : config parm groupings */
+ struct pef_config_parms { /* PEF */
+ struct pef_cfgparm_set_in_progress;
+ struct pef_cfgparm_control;
+ struct pef_cfgparm_action;
+ struct pef_cfgparm_startup_delay; /* in seconds, 1-based */
+ struct pef_cfgparm_alert_startup_delay; /* in seconds, 1-based */
+ struct pef_cfgparm_filter_table_size; /* 1-based, READ-ONLY */
+ struct pef_cfgparm_filter_table_entry;
+ struct pef_cfgparm_filter_table_data_1;
+ struct pef_cfgparm_policy_table_size;
+ struct pef_cfgparm_policy_table_entry;
+ struct pef_cfgparm_system_guid;
+ struct pef_cfgparm_alert_string_table_size;
+ struct pef_cfgparm_alert_string_keys;
+ struct pef_cfgparm_alert_string_table_entry;
+ } __attribute__ ((packed));
+
+ struct pef_lan_config_parms { /* LAN */
+ struct pef_lan_cfgparm_set_in_progress;
+ struct pef_lan_cfgparm_auth_capabilities;
+ struct pef_lan_cfgparm_auth_type;
+ struct pef_lan_cfgparm_ip_address;
+ struct pef_lan_cfgparm_ip_address_source;
+ struct pef_lan_cfgparm_mac_address;
+ struct pef_lan_cfgparm_subnet_mask;
+ struct pef_lan_cfgparm_ipv4_header_parms;
+ struct pef_lan_cfgparm_primary_rmcp_port;
+ struct pef_lan_cfgparm_secondary_rmcp_port;
+ struct pef_lan_cfgparm_bmc_generated_arp_control;
+ struct pef_lan_cfgparm_gratuitous_arp;
+ struct pef_lan_cfgparm_default_gateway_ipaddr;
+ struct pef_lan_cfgparm_default_gateway_macaddr;
+ struct pef_lan_cfgparm_backup_gateway_ipaddr;
+ struct pef_lan_cfgparm_backup_gateway_macaddr;
+ struct pef_lan_cfgparm_pet_community;
+ struct pef_lan_cfgparm_destination_count;
+ struct pef_lan_cfgparm_destination_type;
+ struct pef_lan_cfgparm_destination_ipaddr;
+ } __attribute__ ((packed));
+
+ struct pef_serial_config_parms { /* Serial/PPP */
+ struct pef_serial_cfgparm_set_in_progress;
+ struct pef_serial_cfgparm_auth_capabilities;
+ struct pef_serial_cfgparm_auth_type;
+ struct pef_serial_cfgparm_connection_mode;
+ struct pef_serial_cfgparm_idle_timeout;
+ struct pef_serial_cfgparm_callback_control;
+ struct pef_serial_cfgparm_session_termination;
+ struct pef_serial_cfgparm_ipmi_settings;
+ struct pef_serial_cfgparm_mux_control;
+ struct pef_serial_cfgparm_modem_ring_time;
+ struct pef_serial_cfgparm_modem_init_string;
+ struct pef_serial_cfgparm_modem_escape_sequence;
+ struct pef_serial_cfgparm_modem_hangup_sequence;
+ struct pef_serial_cfgparm_modem_dial_command;
+ struct pef_serial_cfgparm_page_blackout_interval;
+ struct pef_serial_cfgparm_pet_community;
+ struct pef_serial_cfgparm_destination_count;
+ struct pef_serial_cfgparm_destination_info;
+ struct pef_serial_cfgparm_call_retry_interval;
+ struct pef_serial_cfgparm_destination_settings;
+ struct pef_serial_cfgparm_dialstring_count;
+ struct pef_serial_cfgparm_dialstring_info;
+ struct pef_serial_cfgparm_ipaddr_count;
+ struct pef_serial_cfgparm_ipaddr_info;
+ struct pef_serial_cfgparm_tap_acct_count;
+ struct pef_serial_cfgparm_tap_acct_info;
+ struct pef_serial_cfgparm_tap_acct_passwords; /* WRITE only */
+ struct pef_serial_cfgparm_tap_pager_id_strings;
+ struct pef_serial_cfgparm_tap_service_settings;
+ struct pef_serial_cfgparm_terminal_mode_config;
+ struct pef_serial_cfgparm_ppp_otions;
+ struct pef_serial_cfgparm_ppp_primary_rmcp_port;
+ struct pef_serial_cfgparm_ppp_secondary_rmcp_port;
+ struct pef_serial_cfgparm_ppp_link_auth;
+ struct pef_serial_cfgparm_ppp_chap_name;
+ struct pef_serial_cfgparm_ppp_accm;
+ struct pef_serial_cfgparm_ppp_snoop_accm;
+ struct pef_serial_cfgparm_ppp_acct_count;
+ struct pef_serial_cfgparm_ppp_acct_dialstring_selector;
+ struct pef_serial_cfgparm_ppp_acct_ipaddrs;
+ struct pef_serial_cfgparm_ppp_acct_user_names;
+ struct pef_serial_cfgparm_ppp_acct_user_domains;
+ struct pef_serial_cfgparm_ppp_acct_user_passwords; /* WRITE only */
+ struct pef_serial_cfgparm_ppp_acct_auth_settings;
+ struct pef_serial_cfgparm_ppp_acct_connect_hold_times;
+ struct pef_serial_cfgparm_ppp_udp_proxy_ipheader;
+ struct pef_serial_cfgparm_ppp_udp_proxy_xmit_bufsize;
+ struct pef_serial_cfgparm_ppp_udp_proxy_recv_bufsize;
+ struct pef_serial_cfgparm_ppp_remote_console_ipaddr;
+ } __attribute__ ((packed));
+#endif
+
+#define IPMI_CMD_GET_PEF_CAPABILITIES 0x10
+#define IPMI_CMD_GET_PEF_CONFIG_PARMS 0x13
+#define IPMI_CMD_GET_LAST_PROCESSED_EVT_ID 0x15
+#define IPMI_CMD_GET_SYSTEM_GUID 0x37
+#define IPMI_CMD_GET_CHANNEL_INFO 0x42
+#define IPMI_CMD_LAN_GET_CONFIG 0x02
+#define IPMI_CMD_SERIAL_GET_CONFIG 0x11
+
+const char * ipmi_pef_bit_desc(struct bit_desc_map * map, uint32_t val);
+void ipmi_pef_print_flags(struct bit_desc_map * map, flg_e type, uint32_t val);
+void ipmi_pef_print_dec(const char * text, uint32_t val);
+void ipmi_pef_print_hex(const char * text, uint32_t val);
+void ipmi_pef_print_1xd(const char * text, uint32_t val);
+void ipmi_pef_print_2xd(const char * text, uint8_t u1, uint8_t u2);
+void ipmi_pef_print_str(const char * text, const char * val);
+
+int ipmi_pef_main(struct ipmi_intf * intf, int argc, char ** argv);
+
+#endif /* IPMI_PEF_H */
diff --git a/lib/lanplus/inc/ipmitool/ipmi_picmg.h b/lib/lanplus/inc/ipmitool/ipmi_picmg.h
new file mode 100644
index 0000000..ab234e4
--- /dev/null
+++ b/lib/lanplus/inc/ipmitool/ipmi_picmg.h
@@ -0,0 +1,90 @@
+
+/*
+ (C) Kontron
+*/
+
+#ifndef _IPMI_PICMG_H_
+#define _IPMI_PICMG_H_
+
+#include <ipmitool/ipmi.h>
+
+/* PICMG commands */
+#define PICMG_GET_PICMG_PROPERTIES_CMD 0x00
+#define PICMG_GET_ADDRESS_INFO_CMD 0x01
+#define PICMG_GET_SHELF_ADDRESS_INFO_CMD 0x02
+#define PICMG_SET_SHELF_ADDRESS_INFO_CMD 0x03
+#define PICMG_FRU_CONTROL_CMD 0x04
+#define PICMG_GET_FRU_LED_PROPERTIES_CMD 0x05
+#define PICMG_GET_LED_COLOR_CAPABILITIES_CMD 0x06
+#define PICMG_SET_FRU_LED_STATE_CMD 0x07
+#define PICMG_GET_FRU_LED_STATE_CMD 0x08
+#define PICMG_SET_IPMB_CMD 0x09
+#define PICMG_SET_FRU_POLICY_CMD 0x0A
+#define PICMG_GET_FRU_POLICY_CMD 0x0B
+#define PICMG_FRU_ACTIVATION_CMD 0x0C
+#define PICMG_GET_DEVICE_LOCATOR_RECORD_CMD 0x0D
+#define PICMG_SET_PORT_STATE_CMD 0x0E
+#define PICMG_GET_PORT_STATE_CMD 0x0F
+#define PICMG_COMPUTE_POWER_PROPERTIES_CMD 0x10
+#define PICMG_SET_POWER_LEVEL_CMD 0x11
+#define PICMG_GET_POWER_LEVEL_CMD 0x12
+#define PICMG_RENEGOTIATE_POWER_CMD 0x13
+#define PICMG_GET_FAN_SPEED_PROPERTIES_CMD 0x14
+#define PICMG_SET_FAN_LEVEL_CMD 0x15
+#define PICMG_GET_FAN_LEVEL_CMD 0x16
+#define PICMG_BUSED_RESOURCE_CMD 0x17
+
+/* AMC.0 commands */
+#define PICMG_AMC_SET_PORT_STATE_CMD 0x19
+#define PICMG_AMC_GET_PORT_STATE_CMD 0x1A
+
+/* Site Types */
+#define PICMG_ATCA_BOARD 0x00
+#define PICMG_POWER_ENTRY 0x01
+#define PICMG_SHELF_FRU 0x02
+#define PICMG_DEDICATED_SHMC 0x03
+#define PICMG_FAN_TRAY 0x04
+#define PICMG_FAN_FILTER_TRAY 0x05
+#define PICMG_ALARM 0x06
+#define PICMG_AMC 0x07
+#define PICMG_PMC 0x08
+#define PICMG_RTM 0x09
+
+
+
+struct picmg_set_fru_activation_cmd {
+ unsigned char picmg_id; /* always 0*/
+ unsigned char fru_id; /* threshold setting mask */
+ unsigned char fru_state; /* fru activation/deactivation */
+} __attribute__ ((packed));
+
+
+
+/* the LED color capabilities */
+static const char* led_color_str[] __attribute__((unused)) = {
+ "reserved",
+ "BLUE",
+ "RED",
+ "GREEN",
+ "AMBER",
+ "ORANGE",
+ "WHITE",
+ "reserved"
+};
+
+
+
+static const char* amc_link_type_str[] __attribute__((unused)) = {
+ " FRU_PICMGEXT_AMC_LINK_TYPE_RESERVED",
+ " FRU_PICMGEXT_AMC_LINK_TYPE_RESERVED1",
+ " FRU_PICMGEXT_AMC_LINK_TYPE_PCI_EXPRESS",
+ " FRU_PICMGEXT_AMC_LINK_TYPE_ADVANCED_SWITCHING1",
+ " FRU_PICMGEXT_AMC_LINK_TYPE_ADVANCED_SWITCHING2",
+ " FRU_PICMGEXT_AMC_LINK_TYPE_ETHERNET",
+ " FRU_PICMGEXT_AMC_LINK_TYPE_RAPIDIO",
+ " FRU_PICMGEXT_AMC_LINK_TYPE_STORAGE",
+};
+
+int ipmi_picmg_main (struct ipmi_intf * intf, int argc, char ** argv);
+
+#endif
diff --git a/lib/lanplus/inc/ipmitool/ipmi_raw.h b/lib/lanplus/inc/ipmitool/ipmi_raw.h
new file mode 100644
index 0000000..f4364f3
--- /dev/null
+++ b/lib/lanplus/inc/ipmitool/ipmi_raw.h
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+#ifndef IPMI_RAW_H
+#define IPMI_RAW_H
+
+#include <ipmitool/ipmi.h>
+
+int ipmi_raw_main(struct ipmi_intf * intf, int argc, char ** argv);
+struct ipmi_rs * ipmi_master_write_read(struct ipmi_intf * intf, uint8_t bus, uint8_t addr,
+ uint8_t * wdata, uint8_t wsize, uint8_t rsize);
+int ipmi_rawi2c_main(struct ipmi_intf * intf, int argc, char ** argv);
+int ipmi_rawspd_main(struct ipmi_intf * intf, int argc, char ** argv);
+
+#endif /* IPMI_RAW_H */
diff --git a/lib/lanplus/inc/ipmitool/ipmi_sdr.h b/lib/lanplus/inc/ipmitool/ipmi_sdr.h
new file mode 100644
index 0000000..65b5a8c
--- /dev/null
+++ b/lib/lanplus/inc/ipmitool/ipmi_sdr.h
@@ -0,0 +1,876 @@
+/*
+ * 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.
+ */
+
+#ifndef IPMI_SDR_H
+#define IPMI_SDR_H
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef WIN32
+#include <inttypes-win.h>
+#else
+#include <inttypes.h>
+#endif
+#include <math.h>
+#include <ipmitool/bswap.h>
+#include <ipmitool/ipmi.h>
+#include <ipmitool/ipmi_entity.h>
+
+int ipmi_sdr_main(struct ipmi_intf *, int, char **);
+
+#define tos32(val, bits) ((val & ((1<<((bits)-1)))) ? (-((val) & (1<<((bits)-1))) | (val)) : (val))
+
+#if WORDS_BIGENDIAN
+# define __TO_TOL(mtol) (uint16_t)(mtol & 0x3f)
+# define __TO_M(mtol) (int16_t)(tos32((((mtol & 0xff00) >> 8) | ((mtol & 0xc0) << 2)), 10))
+# define __TO_B(bacc) (int32_t)(tos32((((bacc & 0xff000000) >> 24) | ((bacc & 0xc00000) >> 14)), 10))
+# define __TO_ACC(bacc) (uint32_t)(((bacc & 0x3f0000) >> 16) | ((bacc & 0xf000) >> 6))
+# define __TO_ACC_EXP(bacc) (uint32_t)((bacc & 0xc00) >> 10)
+# define __TO_R_EXP(bacc) (int32_t)(tos32(((bacc & 0xf0) >> 4), 4))
+# define __TO_B_EXP(bacc) (int32_t)(tos32((bacc & 0xf), 4))
+#else
+# define __TO_TOL(mtol) (uint16_t)(BSWAP_16(mtol) & 0x3f)
+# define __TO_M(mtol) (int16_t)(tos32((((BSWAP_16(mtol) & 0xff00) >> 8) | ((BSWAP_16(mtol) & 0xc0) << 2)), 10))
+# define __TO_B(bacc) (int32_t)(tos32((((BSWAP_32(bacc) & 0xff000000) >> 24) | \
+ ((BSWAP_32(bacc) & 0xc00000) >> 14)), 10))
+# define __TO_ACC(bacc) (uint32_t)(((BSWAP_32(bacc) & 0x3f0000) >> 16) | ((BSWAP_32(bacc) & 0xf000) >> 6))
+# define __TO_ACC_EXP(bacc) (uint32_t)((BSWAP_32(bacc) & 0xc00) >> 10)
+# define __TO_R_EXP(bacc) (int32_t)(tos32(((BSWAP_32(bacc) & 0xf0) >> 4), 4))
+# define __TO_B_EXP(bacc) (int32_t)(tos32((BSWAP_32(bacc) & 0xf), 4))
+#endif
+
+enum {
+ ANALOG_SENSOR,
+ DISCRETE_SENSOR,
+};
+
+#define READING_UNAVAILABLE 0x20
+#define SCANNING_DISABLED 0x40
+#define EVENT_MSG_DISABLED 0x80
+
+#define IS_READING_UNAVAILABLE(val) ((val) & READING_UNAVAILABLE)
+#define IS_SCANNING_DISABLED(val) (!((val) & SCANNING_DISABLED))
+#define IS_EVENT_MSG_DISABLED(val) (!((val) & EVENT_MSG_DISABLED))
+
+#define GET_SDR_REPO_INFO 0x20
+#define GET_SDR_ALLOC_INFO 0x21
+
+#define SDR_SENSOR_STAT_LO_NC (1<<0)
+#define SDR_SENSOR_STAT_LO_CR (1<<1)
+#define SDR_SENSOR_STAT_LO_NR (1<<2)
+#define SDR_SENSOR_STAT_HI_NC (1<<3)
+#define SDR_SENSOR_STAT_HI_CR (1<<4)
+#define SDR_SENSOR_STAT_HI_NR (1<<5)
+
+#define GET_DEVICE_SDR_INFO 0x20
+#define GET_DEVICE_SDR 0x21
+#define GET_SENSOR_FACTORS 0x23
+#define GET_SENSOR_FACTORS 0x23
+#define SET_SENSOR_HYSTERESIS 0x24
+#define GET_SENSOR_HYSTERESIS 0x25
+#define SET_SENSOR_THRESHOLDS 0x26
+#define GET_SENSOR_THRESHOLDS 0x27
+#define SET_SENSOR_EVENT_ENABLE 0x28
+#define GET_SENSOR_EVENT_ENABLE 0x29
+#define GET_SENSOR_EVENT_STATUS 0x2b
+#define GET_SENSOR_READING 0x2d
+#define GET_SENSOR_TYPE 0x2f
+#define GET_SENSOR_READING 0x2d
+#define GET_SENSOR_TYPE 0x2f
+
+struct sdr_repo_info_rs {
+ uint8_t version; /* SDR version (51h) */
+ uint16_t count; /* number of records */
+ uint16_t free; /* free space in SDR */
+ uint32_t add_stamp; /* last add timestamp */
+ uint32_t erase_stamp; /* last del timestamp */
+ uint8_t op_support; /* supported operations */
+} __attribute__ ((packed));
+
+/* builtin (device) sdrs support */
+struct sdr_device_info_rs {
+ unsigned char count; /* number of records */
+ unsigned char flags; /* flags */
+ unsigned char popChangeInd[3]; /* free space in SDR */
+} __attribute__ ((packed));
+
+#define GET_SDR_RESERVE_REPO 0x22
+struct sdr_reserve_repo_rs {
+ uint16_t reserve_id; /* reservation ID */
+} __attribute__ ((packed));
+
+#define GET_SDR 0x23
+struct sdr_get_rq {
+ uint16_t reserve_id; /* reservation ID */
+ uint16_t id; /* record ID */
+ uint8_t offset; /* offset into SDR */
+#define GET_SDR_ENTIRE_RECORD 0xff
+ uint8_t length; /* length to read */
+} __attribute__ ((packed));
+
+struct sdr_get_rs {
+ uint16_t next; /* next record id */
+ uint16_t id; /* record ID */
+ uint8_t version; /* SDR version (51h) */
+#define SDR_RECORD_TYPE_FULL_SENSOR 0x01
+#define SDR_RECORD_TYPE_COMPACT_SENSOR 0x02
+#define SDR_RECORD_TYPE_EVENTONLY_SENSOR 0x03
+#define SDR_RECORD_TYPE_ENTITY_ASSOC 0x08
+#define SDR_RECORD_TYPE_DEVICE_ENTITY_ASSOC 0x09
+#define SDR_RECORD_TYPE_GENERIC_DEVICE_LOCATOR 0x10
+#define SDR_RECORD_TYPE_FRU_DEVICE_LOCATOR 0x11
+#define SDR_RECORD_TYPE_MC_DEVICE_LOCATOR 0x12
+#define SDR_RECORD_TYPE_MC_CONFIRMATION 0x13
+#define SDR_RECORD_TYPE_BMC_MSG_CHANNEL_INFO 0x14
+#define SDR_RECORD_TYPE_OEM 0xc0
+ uint8_t type; /* record type */
+ uint8_t length; /* remaining record bytes */
+} __attribute__ ((packed));
+
+struct sdr_record_mask {
+ union {
+ struct {
+ uint16_t assert_event; /* assertion event mask */
+ uint16_t deassert_event; /* de-assertion event mask */
+ uint16_t read; /* discrete reading mask */
+ } discrete;
+ struct {
+#if WORDS_BIGENDIAN
+ uint16_t reserved:1;
+ uint16_t status_lnr:1;
+ uint16_t status_lcr:1;
+ uint16_t status_lnc:1;
+ uint16_t assert_unr_high:1;
+ uint16_t assert_unr_low:1;
+ uint16_t assert_ucr_high:1;
+ uint16_t assert_ucr_low:1;
+ uint16_t assert_unc_high:1;
+ uint16_t assert_unc_low:1;
+ uint16_t assert_lnr_high:1;
+ uint16_t assert_lnr_low:1;
+ uint16_t assert_lcr_high:1;
+ uint16_t assert_lcr_low:1;
+ uint16_t assert_lnc_high:1;
+ uint16_t assert_lnc_low:1;
+#else
+ uint16_t assert_lnc_low:1;
+ uint16_t assert_lnc_high:1;
+ uint16_t assert_lcr_low:1;
+ uint16_t assert_lcr_high:1;
+ uint16_t assert_lnr_low:1;
+ uint16_t assert_lnr_high:1;
+ uint16_t assert_unc_low:1;
+ uint16_t assert_unc_high:1;
+ uint16_t assert_ucr_low:1;
+ uint16_t assert_ucr_high:1;
+ uint16_t assert_unr_low:1;
+ uint16_t assert_unr_high:1;
+ uint16_t status_lnc:1;
+ uint16_t status_lcr:1;
+ uint16_t status_lnr:1;
+ uint16_t reserved:1;
+#endif
+#if WORDS_BIGENDIAN
+ uint16_t reserved_2:1;
+ uint16_t status_unr:1;
+ uint16_t status_ucr:1;
+ uint16_t status_unc:1;
+ uint16_t deassert_unr_high:1;
+ uint16_t deassert_unr_low:1;
+ uint16_t deassert_ucr_high:1;
+ uint16_t deassert_ucr_low:1;
+ uint16_t deassert_unc_high:1;
+ uint16_t deassert_unc_low:1;
+ uint16_t deassert_lnr_high:1;
+ uint16_t deassert_lnr_low:1;
+ uint16_t deassert_lcr_high:1;
+ uint16_t deassert_lcr_low:1;
+ uint16_t deassert_lnc_high:1;
+ uint16_t deassert_lnc_low:1;
+#else
+ uint16_t deassert_lnc_low:1;
+ uint16_t deassert_lnc_high:1;
+ uint16_t deassert_lcr_low:1;
+ uint16_t deassert_lcr_high:1;
+ uint16_t deassert_lnr_low:1;
+ uint16_t deassert_lnr_high:1;
+ uint16_t deassert_unc_low:1;
+ uint16_t deassert_unc_high:1;
+ uint16_t deassert_ucr_low:1;
+ uint16_t deassert_ucr_high:1;
+ uint16_t deassert_unr_low:1;
+ uint16_t deassert_unr_high:1;
+ uint16_t status_unc:1;
+ uint16_t status_ucr:1;
+ uint16_t status_unr:1;
+ uint16_t reserved_2:1;
+#endif
+ union {
+ struct {
+#if WORDS_BIGENDIAN /* settable threshold mask */
+ uint16_t reserved:2;
+ uint16_t unr:1;
+ uint16_t ucr:1;
+ uint16_t unc:1;
+ uint16_t lnr:1;
+ uint16_t lcr:1;
+ uint16_t lnc:1;
+ /* padding lower 8 bits */
+ uint16_t readable:8;
+#else
+ uint16_t readable:8;
+ uint16_t lnc:1;
+ uint16_t lcr:1;
+ uint16_t lnr:1;
+ uint16_t unc:1;
+ uint16_t ucr:1;
+ uint16_t unr:1;
+ uint16_t reserved:2;
+#endif
+ } set;
+ struct {
+#if WORDS_BIGENDIAN /* readable threshold mask */
+ /* padding upper 8 bits */
+ uint16_t settable:8;
+ uint16_t reserved:2;
+ uint16_t unr:1;
+ uint16_t ucr:1;
+ uint16_t unc:1;
+ uint16_t lnr:1;
+ uint16_t lcr:1;
+ uint16_t lnc:1;
+#else
+ uint16_t lnc:1;
+ uint16_t lcr:1;
+ uint16_t lnr:1;
+ uint16_t unc:1;
+ uint16_t ucr:1;
+ uint16_t unr:1;
+ uint16_t reserved:2;
+ uint16_t settable:8;
+#endif
+ } read;
+ };
+ } threshold;
+ } type;
+} __attribute__ ((packed));
+
+struct sdr_record_compact_sensor {
+ struct {
+ uint8_t owner_id;
+#if WORDS_BIGENDIAN
+ uint8_t channel:4; /* channel number */
+ uint8_t __reserved1:2;
+ uint8_t lun:2; /* sensor owner lun */
+#else
+ uint8_t lun:2; /* sensor owner lun */
+ uint8_t __reserved1:2;
+ uint8_t channel:4; /* channel number */
+#endif
+ uint8_t sensor_num; /* unique sensor number */
+ } keys;
+
+ struct entity_id entity;
+
+ struct {
+ struct {
+#if WORDS_BIGENDIAN
+ uint8_t __reserved2:1;
+ uint8_t scanning:1;
+ uint8_t events:1;
+ uint8_t thresholds:1;
+ uint8_t hysteresis:1;
+ uint8_t type:1;
+ uint8_t event_gen:1;
+ uint8_t sensor_scan:1;
+#else
+ uint8_t sensor_scan:1;
+ uint8_t event_gen:1;
+ uint8_t type:1;
+ uint8_t hysteresis:1;
+ uint8_t thresholds:1;
+ uint8_t events:1;
+ uint8_t scanning:1;
+ uint8_t __reserved2:1;
+#endif
+ } init;
+ struct {
+#if WORDS_BIGENDIAN
+ uint8_t ignore:1;
+ uint8_t rearm:1;
+ uint8_t hysteresis:2;
+ uint8_t threshold:2;
+ uint8_t event_msg:2;
+#else
+ uint8_t event_msg:2;
+ uint8_t threshold:2;
+ uint8_t hysteresis:2;
+ uint8_t rearm:1;
+ uint8_t ignore:1;
+#endif
+ } capabilities;
+ uint8_t type; /* sensor type */
+ } sensor;
+
+ uint8_t event_type; /* event/reading type code */
+
+ struct sdr_record_mask mask;
+
+ struct {
+#if WORDS_BIGENDIAN
+ uint8_t analog:2;
+ uint8_t rate:3;
+ uint8_t modifier:2;
+ uint8_t pct:1;
+#else
+ uint8_t pct:1;
+ uint8_t modifier:2;
+ uint8_t rate:3;
+ uint8_t analog:2;
+#endif
+ struct {
+ uint8_t base;
+ uint8_t modifier;
+ } type;
+ } unit;
+
+ struct {
+#if WORDS_BIGENDIAN
+ uint8_t __reserved3:2;
+ uint8_t mod_type:2;
+ uint8_t count:4;
+#else
+ uint8_t count:4;
+ uint8_t mod_type:2;
+ uint8_t __reserved3:2;
+#endif
+#if WORDS_BIGENDIAN
+ uint8_t entity_inst:1;
+ uint8_t mod_offset:7;
+#else
+ uint8_t mod_offset:7;
+ uint8_t entity_inst:1;
+#endif
+ } share;
+
+ struct {
+ struct {
+ uint8_t positive;
+ uint8_t negative;
+ } hysteresis;
+ } threshold;
+
+ uint8_t __reserved4[3];
+ uint8_t oem; /* reserved for OEM use */
+ uint8_t id_code; /* sensor ID string type/length code */
+ uint8_t id_string[16]; /* sensor ID string bytes, only if id_code != 0 */
+} __attribute__ ((packed));
+
+struct sdr_record_eventonly_sensor {
+ struct {
+ uint8_t owner_id;
+#if WORDS_BIGENDIAN
+ uint8_t channel:4; /* channel number */
+ uint8_t fru_owner:2; /* fru device owner lun */
+ uint8_t lun:2; /* sensor owner lun */
+#else
+ uint8_t lun:2; /* sensor owner lun */
+ uint8_t fru_owner:2; /* fru device owner lun */
+ uint8_t channel:4; /* channel number */
+#endif
+ uint8_t sensor_num; /* unique sensor number */
+ } keys;
+
+ struct entity_id entity;
+
+ uint8_t sensor_type; /* sensor type */
+ uint8_t event_type; /* event/reading type code */
+
+ struct {
+#if WORDS_BIGENDIAN
+ uint8_t __reserved1:2;
+ uint8_t mod_type:2;
+ uint8_t count:4;
+#else
+ uint8_t count:4;
+ uint8_t mod_type:2;
+ uint8_t __reserved1:2;
+#endif
+#if WORDS_BIGENDIAN
+ uint8_t entity_inst:1;
+ uint8_t mod_offset:7;
+#else
+ uint8_t mod_offset:7;
+ uint8_t entity_inst:1;
+#endif
+ } share;
+
+ uint8_t __reserved4;
+ uint8_t oem; /* reserved for OEM use */
+ uint8_t id_code; /* sensor ID string type/length code */
+ uint8_t id_string[16]; /* sensor ID string bytes, only if id_code != 0 */
+
+} __attribute__ ((packed));
+
+struct sdr_record_full_sensor {
+ struct {
+ uint8_t owner_id;
+#if WORDS_BIGENDIAN
+ uint8_t channel:4; /* channel number */
+ uint8_t __reserved1:2;
+ uint8_t lun:2; /* sensor owner lun */
+#else
+ uint8_t lun:2; /* sensor owner lun */
+ uint8_t __reserved1:2;
+ uint8_t channel:4; /* channel number */
+#endif
+ uint8_t sensor_num; /* unique sensor number */
+ } keys;
+
+ struct entity_id entity;
+
+ struct {
+ struct {
+#if WORDS_BIGENDIAN
+ uint8_t __reserved2:1;
+ uint8_t scanning:1;
+ uint8_t events:1;
+ uint8_t thresholds:1;
+ uint8_t hysteresis:1;
+ uint8_t type:1;
+ uint8_t event_gen:1;
+ uint8_t sensor_scan:1;
+#else
+ uint8_t sensor_scan:1;
+ uint8_t event_gen:1;
+ uint8_t type:1;
+ uint8_t hysteresis:1;
+ uint8_t thresholds:1;
+ uint8_t events:1;
+ uint8_t scanning:1;
+ uint8_t __reserved2:1;
+#endif
+ } init;
+ struct {
+#if WORDS_BIGENDIAN
+ uint8_t ignore:1;
+ uint8_t rearm:1;
+ uint8_t hysteresis:2;
+ uint8_t threshold:2;
+ uint8_t event_msg:2;
+#else
+ uint8_t event_msg:2;
+ uint8_t threshold:2;
+ uint8_t hysteresis:2;
+ uint8_t rearm:1;
+ uint8_t ignore:1;
+#endif
+ } capabilities;
+ uint8_t type;
+ } sensor;
+
+ uint8_t event_type; /* event/reading type code */
+
+ struct sdr_record_mask mask;
+
+ struct {
+#if WORDS_BIGENDIAN
+ uint8_t analog:2;
+ uint8_t rate:3;
+ uint8_t modifier:2;
+ uint8_t pct:1;
+#else
+ uint8_t pct:1;
+ uint8_t modifier:2;
+ uint8_t rate:3;
+ uint8_t analog:2;
+#endif
+ struct {
+ uint8_t base;
+ uint8_t modifier;
+ } type;
+ } unit;
+
+#define SDR_SENSOR_L_LINEAR 0x00
+#define SDR_SENSOR_L_LN 0x01
+#define SDR_SENSOR_L_LOG10 0x02
+#define SDR_SENSOR_L_LOG2 0x03
+#define SDR_SENSOR_L_E 0x04
+#define SDR_SENSOR_L_EXP10 0x05
+#define SDR_SENSOR_L_EXP2 0x06
+#define SDR_SENSOR_L_1_X 0x07
+#define SDR_SENSOR_L_SQR 0x08
+#define SDR_SENSOR_L_CUBE 0x09
+#define SDR_SENSOR_L_SQRT 0x0a
+#define SDR_SENSOR_L_CUBERT 0x0b
+#define SDR_SENSOR_L_NONLINEAR 0x70
+
+ uint8_t linearization; /* 70h=non linear, 71h-7Fh=non linear, OEM */
+ uint16_t mtol; /* M, tolerance */
+ uint32_t bacc; /* accuracy, B, Bexp, Rexp */
+
+ struct {
+#if WORDS_BIGENDIAN
+ uint8_t __reserved3:5;
+ uint8_t normal_min:1; /* normal min field specified */
+ uint8_t normal_max:1; /* normal max field specified */
+ uint8_t nominal_read:1; /* nominal reading field specified */
+#else
+ uint8_t nominal_read:1; /* nominal reading field specified */
+ uint8_t normal_max:1; /* normal max field specified */
+ uint8_t normal_min:1; /* normal min field specified */
+ uint8_t __reserved3:5;
+#endif
+ } analog_flag;
+
+ uint8_t nominal_read; /* nominal reading, raw value */
+ uint8_t normal_max; /* normal maximum, raw value */
+ uint8_t normal_min; /* normal minimum, raw value */
+ uint8_t sensor_max; /* sensor maximum, raw value */
+ uint8_t sensor_min; /* sensor minimum, raw value */
+
+ struct {
+ struct {
+ uint8_t non_recover;
+ uint8_t critical;
+ uint8_t non_critical;
+ } upper;
+ struct {
+ uint8_t non_recover;
+ uint8_t critical;
+ uint8_t non_critical;
+ } lower;
+ struct {
+ uint8_t positive;
+ uint8_t negative;
+ } hysteresis;
+ } threshold;
+ uint8_t __reserved4[2];
+ uint8_t oem; /* reserved for OEM use */
+ uint8_t id_code; /* sensor ID string type/length code */
+ uint8_t id_string[16]; /* sensor ID string bytes, only if id_code != 0 */
+} __attribute__ ((packed));
+
+struct sdr_record_mc_locator {
+ uint8_t dev_slave_addr;
+#if WORDS_BIGENDIAN
+ uint8_t __reserved2:4;
+ uint8_t channel_num:4;
+#else
+ uint8_t channel_num:4;
+ uint8_t __reserved2:4;
+#endif
+#if WORDS_BIGENDIAN
+ uint8_t pwr_state_notif:3;
+ uint8_t __reserved3:1;
+ uint8_t global_init:4;
+#else
+ uint8_t global_init:4;
+ uint8_t __reserved3:1;
+ uint8_t pwr_state_notif:3;
+#endif
+ uint8_t dev_support;
+ uint8_t __reserved4[3];
+ struct entity_id entity;
+ uint8_t oem;
+ uint8_t id_code;
+ uint8_t id_string[16];
+} __attribute__ ((packed));
+
+struct sdr_record_fru_locator {
+ uint8_t dev_slave_addr;
+ uint8_t device_id;
+#if WORDS_BIGENDIAN
+ uint8_t logical:1;
+ uint8_t __reserved2:2;
+ uint8_t lun:2;
+ uint8_t bus:3;
+#else
+ uint8_t bus:3;
+ uint8_t lun:2;
+ uint8_t __reserved2:2;
+ uint8_t logical:1;
+#endif
+#if WORDS_BIGENDIAN
+ uint8_t channel_num:4;
+ uint8_t __reserved3:4;
+#else
+ uint8_t __reserved3:4;
+ uint8_t channel_num:4;
+#endif
+ uint8_t __reserved4;
+ uint8_t dev_type;
+ uint8_t dev_type_modifier;
+ struct entity_id entity;
+ uint8_t oem;
+ uint8_t id_code;
+ uint8_t id_string[16];
+} __attribute__ ((packed));
+
+struct sdr_record_generic_locator {
+ uint8_t dev_access_addr;
+ uint8_t dev_slave_addr;
+#if WORDS_BIGENDIAN
+ uint8_t channel_num:3;
+ uint8_t lun:2;
+ uint8_t bus:3;
+#else
+ uint8_t bus:3;
+ uint8_t lun:2;
+ uint8_t channel_num:3;
+#endif
+#if WORDS_BIGENDIAN
+ uint8_t addr_span:3;
+ uint8_t __reserved1:5;
+#else
+ uint8_t __reserved1:5;
+ uint8_t addr_span:3;
+#endif
+ uint8_t __reserved2;
+ uint8_t dev_type;
+ uint8_t dev_type_modifier;
+ struct entity_id entity;
+ uint8_t oem;
+ uint8_t id_code;
+ uint8_t id_string[16];
+} __attribute__ ((packed));
+
+struct sdr_record_entity_assoc {
+ struct entity_id entity; /* container entity ID and instance */
+ struct {
+#if WORDS_BIGENDIAN
+ uint8_t isrange:1;
+ uint8_t islinked:1;
+ uint8_t isaccessable:1;
+ uint8_t __reserved1:5;
+#else
+ uint8_t __reserved1:5;
+ uint8_t isaccessable:1;
+ uint8_t islinked:1;
+ uint8_t isrange:1;
+#endif
+ } flags;
+ uint8_t entity_id_1; /* entity ID 1 | range 1 entity */
+ uint8_t entity_inst_1; /* entity inst 1 | range 1 first instance */
+ uint8_t entity_id_2; /* entity ID 2 | range 1 entity */
+ uint8_t entity_inst_2; /* entity inst 2 | range 1 last instance */
+ uint8_t entity_id_3; /* entity ID 3 | range 2 entity */
+ uint8_t entity_inst_3; /* entity inst 3 | range 2 first instance */
+ uint8_t entity_id_4; /* entity ID 4 | range 2 entity */
+ uint8_t entity_inst_4; /* entity inst 4 | range 2 last instance */
+} __attribute__ ((packed));
+
+struct sdr_record_oem {
+ uint8_t *data;
+ int data_len;
+};
+
+/*
+ * The Get SDR Repository Info response structure
+ * From table 33-3 of the IPMI v2.0 spec
+ */
+struct get_sdr_repository_info_rsp {
+ uint8_t sdr_version;
+ uint8_t record_count_lsb;
+ uint8_t record_count_msb;
+ uint8_t free_space[2];
+ uint8_t most_recent_addition_timestamp[4];
+ uint8_t most_recent_erase_timestamp[4];
+#if WORDS_BIGENDIAN
+ uint8_t overflow_flag:1;
+ uint8_t modal_update_support:2;
+ uint8_t __reserved1:1;
+ uint8_t delete_sdr_supported:1;
+ uint8_t partial_add_sdr_supported:1;
+ uint8_t reserve_sdr_repository_supported:1;
+ uint8_t get_sdr_repository_allo_info_supported:1;
+#else
+ uint8_t get_sdr_repository_allo_info_supported:1;
+ uint8_t reserve_sdr_repository_supported:1;
+ uint8_t partial_add_sdr_supported:1;
+ uint8_t delete_sdr_supported:1;
+ uint8_t __reserved1:1;
+ uint8_t modal_update_support:2;
+ uint8_t overflow_flag:1;
+#endif
+} __attribute__ ((packed));
+
+struct ipmi_sdr_iterator {
+ uint16_t reservation;
+ int total;
+ int next;
+};
+
+struct sdr_record_list {
+ uint16_t id;
+ uint8_t version;
+ uint8_t type;
+ uint8_t length;
+ uint8_t *raw;
+ 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_generic_locator *genloc;
+ struct sdr_record_fru_locator *fruloc;
+ struct sdr_record_mc_locator *mcloc;
+ struct sdr_record_entity_assoc *entassoc;
+ struct sdr_record_oem *oem;
+ } record;
+};
+
+/* unit description codes (IPMI v1.5 section 37.16) */
+#define UNIT_MAX 0x90
+static const char *unit_desc[] __attribute__ ((unused)) = {
+"unspecified",
+ "degrees C", "degrees F", "degrees K",
+ "Volts", "Amps", "Watts", "Joules",
+ "Coulombs", "VA", "Nits",
+ "lumen", "lux", "Candela",
+ "kPa", "PSI", "Newton",
+ "CFM", "RPM", "Hz",
+ "microsecond", "millisecond", "second", "minute", "hour",
+ "day", "week", "mil", "inches", "feet", "cu in", "cu feet",
+ "mm", "cm", "m", "cu cm", "cu m", "liters", "fluid ounce",
+ "radians", "steradians", "revolutions", "cycles",
+ "gravities", "ounce", "pound", "ft-lb", "oz-in", "gauss",
+ "gilberts", "henry", "millihenry", "farad", "microfarad",
+ "ohms", "siemens", "mole", "becquerel", "PPM", "reserved",
+ "Decibels", "DbA", "DbC", "gray", "sievert",
+ "color temp deg K", "bit", "kilobit", "megabit", "gigabit",
+ "byte", "kilobyte", "megabyte", "gigabyte", "word", "dword",
+ "qword", "line", "hit", "miss", "retry", "reset",
+ "overflow", "underrun", "collision", "packets", "messages",
+ "characters", "error", "correctable error", "uncorrectable error",};
+
+/* sensor type codes (IPMI v1.5 table 36.3)
+ / Updated to v2.0 Table 42-3, Sensor Type Codes */
+#define SENSOR_TYPE_MAX 0x2C
+static const char *sensor_type_desc[] __attribute__ ((unused)) = {
+"reserved",
+ "Temperature", "Voltage", "Current", "Fan",
+ "Physical Security", "Platform Security", "Processor",
+ "Power Supply", "Power Unit", "Cooling Device", "Other",
+ "Memory", "Drive Slot / Bay", "POST Memory Resize",
+ "System Firmwares", "Event Logging Disabled", "Watchdog",
+ "System Event", "Critical Interrupt", "Button",
+ "Module / Board", "Microcontroller", "Add-in Card",
+ "Chassis", "Chip Set", "Other FRU", "Cable / Interconnect",
+ "Terminator", "System Boot Initiated", "Boot Error",
+ "OS Boot", "OS Critical Stop", "Slot / Connector",
+ "System ACPI Power State", "Watchdog", "Platform Alert",
+ "Entity Presence", "Monitor ASIC", "LAN",
+ "Management Subsystem Health", "Battery","Session Audit",
+ "Version Change","FRU State" };
+
+struct ipmi_sdr_iterator *ipmi_sdr_start(struct ipmi_intf *intf);
+struct sdr_get_rs *ipmi_sdr_get_next_header(struct ipmi_intf *intf,
+ struct ipmi_sdr_iterator *i);
+uint8_t *ipmi_sdr_get_record(struct ipmi_intf *intf, struct sdr_get_rs *header,
+ struct ipmi_sdr_iterator *i);
+void ipmi_sdr_end(struct ipmi_intf *intf, struct ipmi_sdr_iterator *i);
+int ipmi_sdr_print_sdr(struct ipmi_intf *intf, uint8_t type);
+int ipmi_sdr_print_rawentry(struct ipmi_intf *intf, uint8_t type, uint8_t * raw,
+ int len);
+int ipmi_sdr_print_listentry(struct ipmi_intf *intf,
+ struct sdr_record_list *entry);
+char *ipmi_sdr_get_unit_string(uint8_t type, uint8_t base, uint8_t modifier);
+const char *ipmi_sdr_get_status(struct sdr_record_full_sensor *sensor,
+ uint8_t stat);
+double sdr_convert_sensor_tolerance(struct sdr_record_full_sensor *sensor,
+ uint8_t val);
+double sdr_convert_sensor_reading(struct sdr_record_full_sensor *sensor,
+ uint8_t val);
+double sdr_convert_sensor_hysterisis(struct sdr_record_full_sensor *sensor,
+ uint8_t val);
+uint8_t sdr_convert_sensor_value_to_raw(struct sdr_record_full_sensor *sensor,
+ double val);
+struct ipmi_rs *ipmi_sdr_get_sensor_reading(struct ipmi_intf *intf,
+ uint8_t sensor);
+struct ipmi_rs *ipmi_sdr_get_sensor_reading_ipmb(struct ipmi_intf *intf,
+ uint8_t sensor,
+ uint8_t target,
+ uint8_t lun);
+struct ipmi_rs *ipmi_sdr_get_sensor_thresholds(struct ipmi_intf *intf,
+ uint8_t sensor);
+struct ipmi_rs *ipmi_sdr_get_sensor_hysteresis(struct ipmi_intf *intf,
+ uint8_t sensor);
+const char *ipmi_sdr_get_sensor_type_desc(const uint8_t type);
+int ipmi_sdr_get_reservation(struct ipmi_intf *intf, uint16_t * reserve_id);
+
+int ipmi_sdr_print_sensor_full(struct ipmi_intf *intf,
+ struct sdr_record_full_sensor *sensor);
+int ipmi_sdr_print_sensor_compact(struct ipmi_intf *intf,
+ struct sdr_record_compact_sensor *sensor);
+int ipmi_sdr_print_sensor_eventonly(struct ipmi_intf *intf,
+ struct sdr_record_eventonly_sensor *sensor);
+int ipmi_sdr_print_sensor_generic_locator(struct ipmi_intf *intf,
+ struct sdr_record_generic_locator
+ *fru);
+int ipmi_sdr_print_sensor_fru_locator(struct ipmi_intf *intf,
+ struct sdr_record_fru_locator *fru);
+int ipmi_sdr_print_sensor_mc_locator(struct ipmi_intf *intf,
+ struct sdr_record_mc_locator *mc);
+int ipmi_sdr_print_sensor_entity_assoc(struct ipmi_intf *intf,
+ struct sdr_record_entity_assoc *assoc);
+
+struct sdr_record_list *ipmi_sdr_find_sdr_byentity(struct ipmi_intf *intf,
+ struct entity_id *entity);
+struct sdr_record_list *ipmi_sdr_find_sdr_bynumtype(struct ipmi_intf *intf,
+ uint8_t num, uint8_t type);
+struct sdr_record_list *ipmi_sdr_find_sdr_bysensortype(struct ipmi_intf *intf,
+ uint8_t type);
+struct sdr_record_list *ipmi_sdr_find_sdr_byid(struct ipmi_intf *intf,
+ char *id);
+struct sdr_record_list *ipmi_sdr_find_sdr_bytype(struct ipmi_intf *intf,
+ uint8_t type);
+int ipmi_sdr_list_cache(struct ipmi_intf *intf);
+int ipmi_sdr_list_cache_fromfile(struct ipmi_intf *intf, const char *ifile);
+void ipmi_sdr_list_empty(struct ipmi_intf *intf);
+int ipmi_sdr_print_info(struct ipmi_intf *intf);
+void ipmi_sdr_print_discrete_state(const char *desc, uint8_t sensor_type,
+ uint8_t event_type, uint8_t state1,
+ uint8_t state2);
+void ipmi_sdr_print_discrete_state_mini(const char *separator,
+ uint8_t sensor_type, uint8_t event_type,
+ uint8_t state1, uint8_t state2);
+int ipmi_sdr_print_sensor_event_status(struct ipmi_intf *intf,
+ uint8_t sensor_num, uint8_t sensor_type,
+ uint8_t event_type, int numeric_fmt);
+int ipmi_sdr_print_sensor_event_enable(struct ipmi_intf *intf,
+ uint8_t sensor_num, uint8_t sensor_type,
+ uint8_t event_type, int numeric_fmt);
+
+#endif /* IPMI_SDR_H */
diff --git a/lib/lanplus/inc/ipmitool/ipmi_sel.h b/lib/lanplus/inc/ipmitool/ipmi_sel.h
new file mode 100644
index 0000000..e4ce1d3
--- /dev/null
+++ b/lib/lanplus/inc/ipmitool/ipmi_sel.h
@@ -0,0 +1,542 @@
+/*
+ * 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.
+ */
+
+#ifndef IPMI_SEL_H
+#define IPMI_SEL_H
+
+#ifdef WIN32
+#include <inttypes-win.h>
+#else
+#include <inttypes.h>
+#endif
+#include <ipmitool/ipmi.h>
+#include <ipmitool/ipmi_sdr.h>
+
+#define IPMI_CMD_GET_SEL_INFO 0x40
+#define IPMI_CMD_GET_SEL_ALLOC_INFO 0x41
+#define IPMI_CMD_RESERVE_SEL 0x42
+#define IPMI_CMD_GET_SEL_ENTRY 0x43
+#define IPMI_CMD_ADD_SEL_ENTRY 0x44
+#define IPMI_CMD_PARTIAL_ADD_SEL_ENTRY 0x45
+#define IPMI_CMD_DELETE_SEL_ENTRY 0x46
+#define IPMI_CMD_CLEAR_SEL 0x47
+#define IPMI_CMD_GET_SEL_TIME 0x48
+#define IPMI_CMD_SET_SEL_TIME 0x49
+#define IPMI_CMD_GET_AUX_LOG_STATUS 0x5A
+#define IPMI_CMD_SET_AUX_LOG_STATUS 0x5B
+
+enum {
+ IPMI_EVENT_CLASS_DISCRETE,
+ IPMI_EVENT_CLASS_DIGITAL,
+ IPMI_EVENT_CLASS_THRESHOLD,
+ IPMI_EVENT_CLASS_OEM,
+};
+
+struct sel_get_rq {
+ uint16_t reserve_id;
+ uint16_t record_id;
+ uint8_t offset;
+ uint8_t length;
+} __attribute__ ((packed));
+
+struct standard_spec_sel_rec{
+ uint32_t timestamp;
+ uint16_t gen_id;
+ uint8_t evm_rev;
+ uint8_t sensor_type;
+ uint8_t sensor_num;
+#if WORDS_BIGENDIAN
+ uint8_t event_dir : 1;
+ uint8_t event_type : 7;
+#else
+ uint8_t event_type : 7;
+ uint8_t event_dir : 1;
+#endif
+#define DATA_BYTE2_SPECIFIED_MASK 0xc0 /* event_data[0] bit mask */
+#define DATA_BYTE3_SPECIFIED_MASK 0x30 /* event_data[0] bit mask */
+#define EVENT_OFFSET_MASK 0x0f /* event_data[0] bit mask */
+ uint8_t event_data[3];
+};
+
+#define SEL_OEM_TS_DATA_LEN 6
+#define SEL_OEM_NOTS_DATA_LEN 13
+struct oem_ts_spec_sel_rec{
+ uint32_t timestamp;
+ uint8_t manf_id[3];
+ uint8_t oem_defined[SEL_OEM_TS_DATA_LEN];
+};
+
+struct oem_nots_spec_sel_rec{
+ uint8_t oem_defined[SEL_OEM_NOTS_DATA_LEN];
+};
+
+struct sel_event_record {
+ uint16_t record_id;
+ uint8_t record_type;
+ union{
+ struct standard_spec_sel_rec standard_type;
+ struct oem_ts_spec_sel_rec oem_ts_type;
+ struct oem_nots_spec_sel_rec oem_nots_type;
+ } sel_type;
+} __attribute__ ((packed));
+
+struct ipmi_event_sensor_types {
+ uint8_t code;
+ uint8_t offset;
+#define ALL_OFFSETS_SPECIFIED 0xff
+ uint8_t data;
+ uint8_t class;
+ const char * type;
+ const char * desc;
+};
+
+static struct ipmi_event_sensor_types generic_event_types[] __attribute__((unused)) = {
+ /* Threshold Based States */
+ { 0x01, 0x00, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Lower Non-critical going low " },
+ { 0x01, 0x01, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Lower Non-critical going high" },
+ { 0x01, 0x02, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Lower Critical going low " },
+ { 0x01, 0x03, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Lower Critical going high" },
+ { 0x01, 0x04, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Lower Non-recoverable going low " },
+ { 0x01, 0x05, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Lower Non-recoverable going high" },
+ { 0x01, 0x06, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Upper Non-critical going low " },
+ { 0x01, 0x07, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Upper Non-critical going high" },
+ { 0x01, 0x08, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Upper Critical going low " },
+ { 0x01, 0x09, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Upper Critical going high" },
+ { 0x01, 0x0a, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Upper Non-recoverable going low " },
+ { 0x01, 0x0b, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Upper Non-recoverable going high" },
+ /* DMI-based "usage state" States */
+ { 0x02, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Usage State", "Transition to Idle" },
+ { 0x02, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Usage State", "Transition to Active" },
+ { 0x02, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Usage State", "Transition to Busy" },
+ /* Digital-Discrete Event States */
+ { 0x03, 0x00, 0xff, IPMI_EVENT_CLASS_DIGITAL, "Digital State", "State Deasserted" },
+ { 0x03, 0x01, 0xff, IPMI_EVENT_CLASS_DIGITAL, "Digital State", "State Asserted" },
+ { 0x04, 0x00, 0xff, IPMI_EVENT_CLASS_DIGITAL, "Digital State", "Predictive Failure Deasserted" },
+ { 0x04, 0x01, 0xff, IPMI_EVENT_CLASS_DIGITAL, "Digital State", "Predictive Failure Asserted" },
+ { 0x05, 0x00, 0xff, IPMI_EVENT_CLASS_DIGITAL, "Digital State", "Limit Not Exceeded" },
+ { 0x05, 0x01, 0xff, IPMI_EVENT_CLASS_DIGITAL, "Digital State", "Limit Exceeded" },
+ { 0x06, 0x00, 0xff, IPMI_EVENT_CLASS_DIGITAL, "Digital State", "Performance Met" },
+ { 0x06, 0x01, 0xff, IPMI_EVENT_CLASS_DIGITAL, "Digital State", "Performance Lags" },
+ /* Severity Event States */
+ { 0x07, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Severity State", "Transition to OK" },
+ { 0x07, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Severity State", "Transition to Non-critical from OK" },
+ { 0x07, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Severity State", "Transition to Critical from less severe" },
+ { 0x07, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Severity State", "Transition to Non-recoverable from less severe" },
+ { 0x07, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Severity State", "Transition to Non-critical from more severe" },
+ { 0x07, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Severity State", "Transition to Critical from Non-recoverable" },
+ { 0x07, 0x06, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Severity State", "Transition to Non-recoverable" },
+ { 0x07, 0x07, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Severity State", "Monitor" },
+ { 0x07, 0x08, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Severity State", "Informational" },
+ /* Availability Status States */
+ { 0x08, 0x00, 0xff, IPMI_EVENT_CLASS_DIGITAL, "Availability State", "Device Absent" },
+ { 0x08, 0x01, 0xff, IPMI_EVENT_CLASS_DIGITAL, "Availability State", "Device Present" },
+ { 0x09, 0x00, 0xff, IPMI_EVENT_CLASS_DIGITAL, "Availability State", "Device Disabled" },
+ { 0x09, 0x01, 0xff, IPMI_EVENT_CLASS_DIGITAL, "Availability State", "Device Enabled" },
+ { 0x0a, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Availability State", "Transition to Running" },
+ { 0x0a, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Availability State", "Transition to In Test" },
+ { 0x0a, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Availability State", "Transition to Power Off" },
+ { 0x0a, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Availability State", "Transition to On Line" },
+ { 0x0a, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Availability State", "Transition to Off Line" },
+ { 0x0a, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Availability State", "Transition to Off Duty" },
+ { 0x0a, 0x06, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Availability State", "Transition to Degraded" },
+ { 0x0a, 0x07, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Availability State", "Transition to Power Save" },
+ { 0x0a, 0x08, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Availability State", "Install Error" },
+ /* Redundancy States */
+ { 0x0b, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Redundancy State", "Fully Redundant" },
+ { 0x0b, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Redundancy State", "Redundancy Lost" },
+ { 0x0b, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Redundancy State", "Redundancy Degraded" },
+ { 0x0b, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Redundancy State", "Non-Redundant: Sufficient from Redundant" },
+ { 0x0b, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Redundancy State", "Non-Redundant: Sufficient from Insufficient" },
+ { 0x0b, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Redundancy State", "Non-Redundant: Insufficient Resources" },
+ { 0x0b, 0x06, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Redundancy State", "Redundancy Degraded from Fully Redundant" },
+ { 0x0b, 0x07, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Redundancy State", "Redundancy Degraded from Non-Redundant" },
+ /* ACPI Device Power States */
+ { 0x0c, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "ACPI Device Power State", "D0 Power State" },
+ { 0x0c, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "ACPI Device Power State", "D1 Power State" },
+ { 0x0c, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "ACPI Device Power State", "D2 Power State" },
+ { 0x0c, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "ACPI Device Power State", "D3 Power State" },
+ /* END */
+ { 0x00, 0x00, 0xff, 0x00, NULL, NULL },
+};
+
+static struct ipmi_event_sensor_types sensor_specific_types[] __attribute__((unused)) = {
+ { 0x00, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Reserved", NULL },
+ { 0x01, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Temperature", NULL },
+ { 0x02, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Voltage", NULL },
+ { 0x03, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Current", NULL },
+ { 0x04, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Fan", NULL },
+
+ { 0x05, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Physical Security", "General Chassis intrusion" },
+ { 0x05, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Physical Security", "Drive Bay intrusion" },
+ { 0x05, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Physical Security", "I/O Card area intrusion" },
+ { 0x05, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Physical Security", "Processor area intrusion" },
+ { 0x05, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Physical Security", "System unplugged from LAN" },
+ { 0x05, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Physical Security", "Unauthorized dock" },
+ { 0x05, 0x06, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Physical Security", "FAN area intrusion" },
+
+ { 0x06, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Platform Security", "Front Panel Lockout violation attempted" },
+ { 0x06, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Platform Security", "Pre-boot password violation - user password" },
+ { 0x06, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Platform Security", "Pre-boot password violation - setup password" },
+ { 0x06, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Platform Security", "Pre-boot password violation - network boot password" },
+ { 0x06, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Platform Security", "Other pre-boot password violation" },
+ { 0x06, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Platform Security", "Out-of-band access password violation" },
+
+ { 0x07, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Processor", "IERR" },
+ { 0x07, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Processor", "Thermal Trip" },
+ { 0x07, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Processor", "FRB1/BIST failure" },
+ { 0x07, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Processor", "FRB2/Hang in POST failure" },
+ { 0x07, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Processor", "FRB3/Processor startup/init failure" },
+ { 0x07, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Processor", "Configuration Error" },
+ { 0x07, 0x06, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Processor", "SM BIOS Uncorrectable CPU-complex Error" },
+ { 0x07, 0x07, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Processor", "Presence detected" },
+ { 0x07, 0x08, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Processor", "Disabled" },
+ { 0x07, 0x09, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Processor", "Terminator presence detected" },
+ { 0x07, 0x0a, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Processor", "Throttled" },
+
+ { 0x08, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Power Supply", "Presence detected" },
+ { 0x08, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Power Supply", "Failure detected" },
+ { 0x08, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Power Supply", "Predictive failure" },
+ { 0x08, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Power Supply", "Power Supply AC lost" },
+ { 0x08, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Power Supply", "AC lost or out-of-range" },
+ { 0x08, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Power Supply", "AC out-of-range, but present" },
+ { 0x08, 0x06, 0x00, IPMI_EVENT_CLASS_DISCRETE, "Power Supply", "Config Error: Vendor Mismatch" },
+ { 0x08, 0x06, 0x01, IPMI_EVENT_CLASS_DISCRETE, "Power Supply", "Config Error: Revision Mismatch" },
+ { 0x08, 0x06, 0x02, IPMI_EVENT_CLASS_DISCRETE, "Power Supply", "Config Error: Processor Missing" },
+ { 0x08, 0x06, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Power Supply", "Config Error" },
+
+ { 0x09, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Power Unit", "Power off/down" },
+ { 0x09, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Power Unit", "Power cycle" },
+ { 0x09, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Power Unit", "240VA power down" },
+ { 0x09, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Power Unit", "Interlock power down" },
+ { 0x09, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Power Unit", "AC lost" },
+ { 0x09, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Power Unit", "Soft-power control failure" },
+ { 0x09, 0x06, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Power Unit", "Failure detected" },
+ { 0x09, 0x07, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Power Unit", "Predictive failure" },
+
+ { 0x0a, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Cooling Device", NULL },
+ { 0x0b, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Other Units-based Sensor", NULL },
+
+ { 0x0c, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Memory", "Correctable ECC" },
+ { 0x0c, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Memory", "Uncorrectable ECC" },
+ { 0x0c, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Memory", "Parity" },
+ { 0x0c, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Memory", "Memory Scrub Failed" },
+ { 0x0c, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Memory", "Memory Device Disabled" },
+ { 0x0c, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Memory", "Correctable ECC logging limit reached" },
+ { 0x0c, 0x06, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Memory", "Presence Detected" },
+ { 0x0c, 0x07, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Memory", "Configuration Error" },
+ { 0x0c, 0x08, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Memory", "Spare" },
+ { 0x0c, 0x09, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Memory", "Throttled" },
+
+ { 0x0d, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Drive Slot", "Drive Present" },
+ { 0x0d, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Drive Slot", "Drive Fault" },
+ { 0x0d, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Drive Slot", "Predictive Failure" },
+ { 0x0d, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Drive Slot", "Hot Spare" },
+ { 0x0d, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Drive Slot", "Parity Check In Progress" },
+ { 0x0d, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Drive Slot", "In Critical Array" },
+ { 0x0d, 0x06, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Drive Slot", "In Failed Array" },
+ { 0x0d, 0x07, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Drive Slot", "Rebuild In Progress" },
+ { 0x0d, 0x08, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Drive Slot", "Rebuild Aborted" },
+
+ { 0x0e, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "POST Memory Resize", NULL },
+
+ { 0x0f, 0x00, 0x00, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Error", "Unspecified" },
+ { 0x0f, 0x00, 0x01, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Error", "No system memory installed" },
+ { 0x0f, 0x00, 0x02, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Error", "No usable system memory" },
+ { 0x0f, 0x00, 0x03, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Error", "Unrecoverable IDE device failure" },
+ { 0x0f, 0x00, 0x04, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Error", "Unrecoverable system-board failure" },
+ { 0x0f, 0x00, 0x05, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Error", "Unrecoverable diskette failure" },
+ { 0x0f, 0x00, 0x06, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Error", "Unrecoverable hard-disk controller failure" },
+ { 0x0f, 0x00, 0x07, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Error", "Unrecoverable PS/2 or USB keyboard failure" },
+ { 0x0f, 0x00, 0x08, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Error", "Removable boot media not found" },
+ { 0x0f, 0x00, 0x09, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Error", "Unrecoverable video controller failure" },
+ { 0x0f, 0x00, 0x0a, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Error", "No video device selected" },
+ { 0x0f, 0x00, 0x0b, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Error", "BIOS corruption detected" },
+ { 0x0f, 0x00, 0x0c, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Error", "CPU voltage mismatch" },
+ { 0x0f, 0x00, 0x0d, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Error", "CPU speed mismatch failure" },
+ { 0x0f, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Error", "Unknown Error" },
+
+ { 0x0f, 0x01, 0x00, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Unspecified" },
+ { 0x0f, 0x01, 0x01, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Memory initialization" },
+ { 0x0f, 0x01, 0x02, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Hard-disk initialization" },
+ { 0x0f, 0x01, 0x03, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Secondary CPU Initialization" },
+ { 0x0f, 0x01, 0x04, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "User authentication" },
+ { 0x0f, 0x01, 0x05, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "User-initiated system setup" },
+ { 0x0f, 0x01, 0x06, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "USB resource configuration" },
+ { 0x0f, 0x01, 0x07, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "PCI resource configuration" },
+ { 0x0f, 0x01, 0x08, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Option ROM initialization" },
+ { 0x0f, 0x01, 0x09, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Video initialization" },
+ { 0x0f, 0x01, 0x0a, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Cache initialization" },
+ { 0x0f, 0x01, 0x0b, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "SMBus initialization" },
+ { 0x0f, 0x01, 0x0c, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Keyboard controller initialization" },
+ { 0x0f, 0x01, 0x0d, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Management controller initialization" },
+ { 0x0f, 0x01, 0x0e, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Docking station attachment" },
+ { 0x0f, 0x01, 0x0f, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Enabling docking station" },
+ { 0x0f, 0x01, 0x10, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Docking station ejection" },
+ { 0x0f, 0x01, 0x11, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Disabling docking station" },
+ { 0x0f, 0x01, 0x12, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Calling operating system wake-up vector" },
+ { 0x0f, 0x01, 0x13, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "System boot initiated" },
+ { 0x0f, 0x01, 0x14, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Motherboard initialization" },
+ { 0x0f, 0x01, 0x15, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "reserved" },
+ { 0x0f, 0x01, 0x16, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Floppy initialization" },
+ { 0x0f, 0x01, 0x17, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Keyboard test" },
+ { 0x0f, 0x01, 0x18, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Pointing device test" },
+ { 0x0f, 0x01, 0x19, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Primary CPU initialization" },
+ { 0x0f, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Hang", "Unknown Hang" },
+
+ { 0x0f, 0x02, 0x00, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Unspecified" },
+ { 0x0f, 0x02, 0x01, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Memory initialization" },
+ { 0x0f, 0x02, 0x02, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Hard-disk initialization" },
+ { 0x0f, 0x02, 0x03, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Secondary CPU Initialization" },
+ { 0x0f, 0x02, 0x04, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "User authentication" },
+ { 0x0f, 0x02, 0x05, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "User-initiated system setup" },
+ { 0x0f, 0x02, 0x06, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "USB resource configuration" },
+ { 0x0f, 0x02, 0x07, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "PCI resource configuration" },
+ { 0x0f, 0x02, 0x08, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Option ROM initialization" },
+ { 0x0f, 0x02, 0x09, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Video initialization" },
+ { 0x0f, 0x02, 0x0a, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Cache initialization" },
+ { 0x0f, 0x02, 0x0b, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "SMBus initialization" },
+ { 0x0f, 0x02, 0x0c, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Keyboard controller initialization" },
+ { 0x0f, 0x02, 0x0d, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Management controller initialization" },
+ { 0x0f, 0x02, 0x0e, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Docking station attachment" },
+ { 0x0f, 0x02, 0x0f, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Enabling docking station" },
+ { 0x0f, 0x02, 0x10, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Docking station ejection" },
+ { 0x0f, 0x02, 0x11, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Disabling docking station" },
+ { 0x0f, 0x02, 0x12, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Calling operating system wake-up vector" },
+ { 0x0f, 0x02, 0x13, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "System boot initiated" },
+ { 0x0f, 0x02, 0x14, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Motherboard initialization" },
+ { 0x0f, 0x02, 0x15, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "reserved" },
+ { 0x0f, 0x02, 0x16, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Floppy initialization" },
+ { 0x0f, 0x02, 0x17, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Keyboard test" },
+ { 0x0f, 0x02, 0x18, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Pointing device test" },
+ { 0x0f, 0x02, 0x19, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Primary CPU initialization" },
+ { 0x0f, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Firmware Progress", "Unknown Progress" },
+
+ { 0x10, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Event Logging Disabled", "Correctable memory error logging disabled" },
+ { 0x10, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Event Logging Disabled", "Event logging disabled" },
+ { 0x10, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Event Logging Disabled", "Log area reset/cleared" },
+ { 0x10, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Event Logging Disabled", "All event logging disabled" },
+ { 0x10, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Event Logging Disabled", "Log full" },
+ { 0x10, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Event Logging Disabled", "Log almost full" },
+
+ { 0x11, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Watchdog 1", "BIOS Reset" },
+ { 0x11, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Watchdog 1", "OS Reset" },
+ { 0x11, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Watchdog 1", "OS Shut Down" },
+ { 0x11, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Watchdog 1", "OS Power Down" },
+ { 0x11, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Watchdog 1", "OS Power Cycle" },
+ { 0x11, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Watchdog 1", "OS NMI/Diag Interrupt" },
+ { 0x11, 0x06, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Watchdog 1", "OS Expired" },
+ { 0x11, 0x07, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Watchdog 1", "OS pre-timeout Interrupt" },
+
+ { 0x12, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Event", "System Reconfigured" },
+ { 0x12, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Event", "OEM System boot event" },
+ { 0x12, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Event", "Undetermined system hardware failure" },
+ { 0x12, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Event", "Entry added to auxiliary log" },
+ { 0x12, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Event", "PEF Action" },
+ { 0x12, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Event", "Timestamp Clock Sync" },
+
+ { 0x13, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Critical Interrupt", "NMI/Diag Interrupt" },
+ { 0x13, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Critical Interrupt", "Bus Timeout" },
+ { 0x13, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Critical Interrupt", "I/O Channel check NMI" },
+ { 0x13, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Critical Interrupt", "Software NMI" },
+ { 0x13, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Critical Interrupt", "PCI PERR" },
+ { 0x13, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Critical Interrupt", "PCI SERR" },
+ { 0x13, 0x06, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Critical Interrupt", "EISA failsafe timeout" },
+ { 0x13, 0x07, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Critical Interrupt", "Bus Correctable error" },
+ { 0x13, 0x08, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Critical Interrupt", "Bus Uncorrectable error" },
+ { 0x13, 0x09, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Critical Interrupt", "Fatal NMI" },
+ { 0x13, 0x0a, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Critical Interrupt", "Bus Fatal Error" },
+
+ { 0x14, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Button", "Power Button pressed" },
+ { 0x14, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Button", "Sleep Button pressed" },
+ { 0x14, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Button", "Reset Button pressed" },
+ { 0x14, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Button", "FRU Latch" },
+ { 0x14, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Button", "FRU Service" },
+
+ { 0x15, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Module/Board", NULL },
+ { 0x16, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Microcontroller/Coprocessor", NULL },
+ { 0x17, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Add-in Card", NULL },
+ { 0x18, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Chassis", NULL },
+ { 0x19, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Chip Set", NULL },
+ { 0x1a, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Other FRU", NULL },
+
+ { 0x1b, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Cable/Interconnect", "Connected" },
+ { 0x1b, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Cable/Interconnect", "Config Error" },
+
+ { 0x1c, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Terminator", NULL },
+
+ { 0x1d, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Boot Initiated", "Initiated by power up" },
+ { 0x1d, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Boot Initiated", "Initiated by hard reset" },
+ { 0x1d, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Boot Initiated", "Initiated by warm reset" },
+ { 0x1d, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Boot Initiated", "User requested PXE boot" },
+ { 0x1d, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Boot Initiated", "Automatic boot to diagnostic" },
+ { 0x1d, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Boot Initiated", "OS initiated hard reset" },
+ { 0x1d, 0x06, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Boot Initiated", "OS initiated warm reset" },
+ { 0x1d, 0x07, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System Boot Initiated", "System Restart" },
+
+ { 0x1e, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Boot Error", "No bootable media" },
+ { 0x1e, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Boot Error", "Non-bootable disk in drive" },
+ { 0x1e, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Boot Error", "PXE server not found" },
+ { 0x1e, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Boot Error", "Invalid boot sector" },
+ { 0x1e, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Boot Error", "Timeout waiting for selection" },
+
+ { 0x1f, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "OS Boot", "A: boot completed" },
+ { 0x1f, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "OS Boot", "C: boot completed" },
+ { 0x1f, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "OS Boot", "PXE boot completed" },
+ { 0x1f, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "OS Boot", "Diagnostic boot completed" },
+ { 0x1f, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "OS Boot", "CD-ROM boot completed" },
+ { 0x1f, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "OS Boot", "ROM boot completed" },
+ { 0x1f, 0x06, 0xff, IPMI_EVENT_CLASS_DISCRETE, "OS Boot", "boot completed - device not specified" },
+
+ { 0x20, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "OS Stop/Shutdown", "Error during system startup" },
+ { 0x20, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "OS Stop/Shutdown", "Run-time critical stop" },
+ { 0x20, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "OS Stop/Shutdown", "OS graceful stop" },
+ { 0x20, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "OS Stop/Shutdown", "OS graceful shutdown" },
+ { 0x20, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "OS Stop/Shutdown", "PEF initiated soft shutdown" },
+ { 0x20, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "OS Stop/Shutdown", "Agent not responding" },
+
+ { 0x21, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Fault Status" },
+ { 0x21, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Identify Status" },
+ { 0x21, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Device Installed" },
+ { 0x21, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Ready for Device Installation" },
+ { 0x21, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Ready for Device Removal" },
+ { 0x21, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Slot Power is Off" },
+ { 0x21, 0x06, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Device Removal Request" },
+ { 0x21, 0x07, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Interlock" },
+ { 0x21, 0x08, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Slot is Disabled" },
+ { 0x21, 0x09, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Slot/Connector", "Spare Device" },
+
+ { 0x22, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System ACPI Power State", "S0/G0: working" },
+ { 0x22, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System ACPI Power State", "S1: sleeping with system hw & processor context maintained" },
+ { 0x22, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System ACPI Power State", "S2: sleeping, processor context lost" },
+ { 0x22, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System ACPI Power State", "S3: sleeping, processor & hw context lost, memory retained" },
+ { 0x22, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System ACPI Power State", "S4: non-volatile sleep/suspend-to-disk" },
+ { 0x22, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System ACPI Power State", "S5/G2: soft-off" },
+ { 0x22, 0x06, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System ACPI Power State", "S4/S5: soft-off" },
+ { 0x22, 0x07, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System ACPI Power State", "G3: mechanical off" },
+ { 0x22, 0x08, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System ACPI Power State", "Sleeping in S1/S2/S3 state" },
+ { 0x22, 0x09, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System ACPI Power State", "G1: sleeping" },
+ { 0x22, 0x0a, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System ACPI Power State", "S5: entered by override" },
+ { 0x22, 0x0b, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System ACPI Power State", "Legacy ON state" },
+ { 0x22, 0x0c, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System ACPI Power State", "Legacy OFF state" },
+ { 0x22, 0x0e, 0xff, IPMI_EVENT_CLASS_DISCRETE, "System ACPI Power State", "Unknown" },
+
+ { 0x23, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Watchdog 2", "Timer expired" },
+ { 0x23, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Watchdog 2", "Hard reset" },
+ { 0x23, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Watchdog 2", "Power down" },
+ { 0x23, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Watchdog 2", "Power cycle" },
+ { 0x23, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Watchdog 2", "reserved" },
+ { 0x23, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Watchdog 2", "reserved" },
+ { 0x23, 0x06, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Watchdog 2", "reserved" },
+ { 0x23, 0x07, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Watchdog 2", "reserved" },
+ { 0x23, 0x08, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Watchdog 2", "Timer interrupt" },
+
+ { 0x24, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Platform Alert", "Platform generated page" },
+ { 0x24, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Platform Alert", "Platform generated LAN alert" },
+ { 0x24, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Platform Alert", "Platform Event Trap generated" },
+ { 0x24, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Platform Alert", "Platform generated SNMP trap, OEM format" },
+
+ { 0x25, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Entity Presence", "Present" },
+ { 0x25, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Entity Presence", "Absent" },
+ { 0x25, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Entity Presence", "Disabled" },
+
+ { 0x26, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Monitor ASIC/IC", NULL },
+
+ { 0x27, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "LAN", "Heartbeat Lost" },
+ { 0x27, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "LAN", "Heartbeat" },
+
+ { 0x28, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Management Subsystem Health", "Sensor access degraded or unavailable" },
+ { 0x28, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Management Subsystem Health", "Controller access degraded or unavailable" },
+ { 0x28, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Management Subsystem Health", "Management controller off-line" },
+ { 0x28, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Management Subsystem Health", "Management controller unavailable" },
+ { 0x28, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Management Subsystem Health", "Sensor failure" },
+ { 0x28, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Management Subsystem Health", "FRU failure" },
+
+ { 0x29, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Battery", "Low" },
+ { 0x29, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Battery", "Failed" },
+ { 0x29, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Battery", "Presence Detected" },
+
+ { 0x2b, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Version Change", "Hardware change detected" },
+ { 0x2b, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Version Change", "Firmware or software change detected" },
+ { 0x2b, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Version Change", "Hardware incompatibility detected" },
+ { 0x2b, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Version Change", "Firmware or software incompatibility detected" },
+ { 0x2b, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Version Change", "Invalid or unsupported hardware version" },
+ { 0x2b, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Version Change", "Invalid or unsupported firmware or software version" },
+ { 0x2b, 0x06, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Version Change", "Hardware change success" },
+ { 0x2b, 0x07, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Version Change", "Firmware or software change success" },
+
+ { 0x2c, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "FRU State", "Not Installed" },
+ { 0x2c, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "FRU State", "Inactive" },
+ { 0x2c, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "FRU State", "Activation Requested" },
+ { 0x2c, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "FRU State", "Activation in Progress" },
+ { 0x2c, 0x04, 0xff, IPMI_EVENT_CLASS_DISCRETE, "FRU State", "Active" },
+ { 0x2c, 0x05, 0xff, IPMI_EVENT_CLASS_DISCRETE, "FRU State", "Deactivation Requested" },
+ { 0x2c, 0x06, 0xff, IPMI_EVENT_CLASS_DISCRETE, "FRU State", "Deactivation in Progress" },
+ { 0x2c, 0x07, 0xff, IPMI_EVENT_CLASS_DISCRETE, "FRU State", "Communication lost" },
+
+ { 0xF0, 0x00, 0xFF, IPMI_EVENT_CLASS_DISCRETE, "FRU Hot Swap", "Transition to M0" },
+ { 0xF0, 0x01, 0xFF, IPMI_EVENT_CLASS_DISCRETE, "FRU Hot Swap", "Transition to M1" },
+ { 0xF0, 0x02, 0xFF, IPMI_EVENT_CLASS_DISCRETE, "FRU Hot Swap", "Transition to M2" },
+ { 0xF0, 0x03, 0xFF, IPMI_EVENT_CLASS_DISCRETE, "FRU Hot Swap", "Transition to M3" },
+ { 0xF0, 0x04, 0xFF, IPMI_EVENT_CLASS_DISCRETE, "FRU Hot Swap", "Transition to M4" },
+ { 0xF0, 0x05, 0xFF, IPMI_EVENT_CLASS_DISCRETE, "FRU Hot Swap", "Transition to M5" },
+ { 0xF0, 0x06, 0xFF, IPMI_EVENT_CLASS_DISCRETE, "FRU Hot Swap", "Transition to M6" },
+ { 0xF0, 0x06, 0xFF, IPMI_EVENT_CLASS_DISCRETE, "FRU Hot Swap", "Transition to M7" },
+
+ { 0xF1, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "IPMB-0 Status", "IPMB-A disabled, IPMB-B disabled" },
+ { 0xF1, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "IPMB-0 Status", "IPMB-A enabled, IPMB-B disabled" },
+ { 0xF1, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "IPMB-0 Status", "IPMB-A disabled, IPMB-B enabled" },
+ { 0xF1, 0x03, 0xff, IPMI_EVENT_CLASS_DISCRETE, "IPMB-0 Status", "IPMB-A enabled, IPMP-B enabled" },
+
+ { 0xF2, 0x00, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Module Hot Swap", "Module Handle Closed" },
+ { 0xF2, 0x01, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Module Hot Swap", "Module Handle Opened" },
+ { 0xF2, 0x02, 0xff, IPMI_EVENT_CLASS_DISCRETE, "Module Hot Swap", "Quiesced" },
+
+ { 0xC0, 0x00, 0xff, 0x00, "OEM", "OEM Specific" },
+
+ { 0x00, 0x00, 0x00, 0x00, NULL, NULL },
+};
+
+int ipmi_sel_main(struct ipmi_intf *, int, char **);
+void ipmi_sel_print_std_entry(struct ipmi_intf * intf, struct sel_event_record * evt);
+void ipmi_sel_print_std_entry_verbose(struct ipmi_intf * intf, struct sel_event_record * evt);
+void ipmi_sel_print_extended_entry(struct ipmi_intf * intf, struct sel_event_record * evt);
+void ipmi_sel_print_extended_entry_verbose(struct ipmi_intf * intf, struct sel_event_record * evt);
+void ipmi_get_event_desc(struct ipmi_intf * intf, struct sel_event_record * rec, char ** desc);
+const char * ipmi_sel_get_sensor_type(uint8_t code);
+const char * ipmi_sel_get_sensor_type_offset(uint8_t code, uint8_t offset);
+uint16_t ipmi_sel_get_std_entry(struct ipmi_intf * intf, uint16_t id, struct sel_event_record * evt);
+char * get_newisys_evt_desc(struct ipmi_intf * intf, struct sel_event_record * rec);
+IPMI_OEM ipmi_get_oem(struct ipmi_intf * intf);
+char * ipmi_get_oem_desc(struct ipmi_intf * intf, struct sel_event_record * rec);
+int ipmi_sel_oem_init(const char * filename);
+
+#endif /* IPMI_SEL_H */
diff --git a/lib/lanplus/inc/ipmitool/ipmi_sensor.h b/lib/lanplus/inc/ipmitool/ipmi_sensor.h
new file mode 100644
index 0000000..8c145cf
--- /dev/null
+++ b/lib/lanplus/inc/ipmitool/ipmi_sensor.h
@@ -0,0 +1,84 @@
+/*
+ * 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.
+ */
+
+#ifndef IPMI_SENSOR_H
+#define IPMI_SENSOR_H
+
+#include <math.h>
+#include <ipmitool/bswap.h>
+#include <ipmitool/ipmi.h>
+#include <ipmitool/ipmi_sdr.h>
+
+/* 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 {
+ uint8_t sensor_num; /* sensor # */
+ uint8_t set_mask; /* threshold setting mask */
+ uint8_t lower_non_crit; /* new lower non critical threshold*/
+ uint8_t lower_crit; /* new lower critical threshold*/
+ uint8_t lower_non_recov; /* new lower non recoverable threshold*/
+ uint8_t upper_non_crit; /* new upper non critical threshold*/
+ uint8_t upper_crit; /* new upper critical threshold*/
+ uint8_t upper_non_recov; /* new upper non recoverable threshold*/
+} __attribute__ ((packed));
+
+
+int ipmi_sensor_main(struct ipmi_intf *, int, char **);
+int ipmi_sensor_print_full(struct ipmi_intf *, struct sdr_record_full_sensor *);
+int ipmi_sensor_print_compact(struct ipmi_intf *, struct sdr_record_compact_sensor *);
+
+#endif /* IPMI_SENSOR_H */
diff --git a/lib/lanplus/inc/ipmitool/ipmi_session.h b/lib/lanplus/inc/ipmitool/ipmi_session.h
new file mode 100644
index 0000000..ad7a09c
--- /dev/null
+++ b/lib/lanplus/inc/ipmitool/ipmi_session.h
@@ -0,0 +1,125 @@
+/*
+ * 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.
+ */
+
+#ifndef IPMI_SESSION_H
+#define IPMI_SESSION_H
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <ipmitool/ipmi.h>
+
+#define IPMI_GET_SESSION_INFO 0x3D
+
+/*
+ * From table 22.25 of the IPMIv2 specification
+ */
+struct get_session_info_rsp
+{
+ uint8_t session_handle;
+
+ #if WORDS_BIGENDIAN
+ uint8_t __reserved1 : 2;
+ uint8_t session_slot_count : 6; /* 1-based */
+ #else
+ uint8_t session_slot_count : 6; /* 1-based */
+ uint8_t __reserved1 : 2;
+ #endif
+
+ #if WORDS_BIGENDIAN
+ uint8_t __reserved2 : 2;
+ uint8_t active_session_count : 6; /* 1-based */
+ #else
+ uint8_t active_session_count : 6; /* 1-based */
+ uint8_t __reserved2 : 2;
+ #endif
+
+ #if WORDS_BIGENDIAN
+ uint8_t __reserved3 : 2;
+ uint8_t user_id : 6;
+ #else
+ uint8_t user_id : 6;
+ uint8_t __reserved3 : 2;
+ #endif
+
+ #if WORDS_BIGENDIAN
+ uint8_t __reserved4 : 4;
+ uint8_t privilege_level : 4;
+ #else
+ uint8_t privilege_level : 4;
+ uint8_t __reserved4 : 4;
+ #endif
+
+ #if WORDS_BIGENDIAN
+ uint8_t auxiliary_data : 4;
+ uint8_t channel_number : 4;
+ #else
+ uint8_t channel_number : 4;
+ uint8_t auxiliary_data : 4;
+ #endif
+
+ union
+ {
+ /* Only exists if channel type is 802.3 LAN */
+ struct
+ {
+ uint8_t console_ip[4]; /* MSBF */
+ uint8_t console_mac[6]; /* MSBF */
+ uint16_t console_port; /* LSBF */
+ } lan_data;
+
+ /* Only exists if channel type is async. serial modem */
+ struct
+ {
+ uint8_t session_channel_activity_type;
+
+ #if WORDS_BIGENDIAN
+ uint8_t __reserved5 : 4;
+ uint8_t destination_selector : 4;
+ #else
+ uint8_t destination_selector : 4;
+ uint8_t __reserved5 : 4;
+ #endif
+
+ uint8_t console_ip[4]; /* MSBF */
+
+ /* Only exists if session is PPP */
+ uint16_t console_port; /* LSBF */
+ } modem_data;
+ } channel_data;
+} __attribute__ ((packed));
+
+
+
+int ipmi_session_main(struct ipmi_intf *, int, char **);
+
+#endif /*IPMI_CHANNEL_H*/
diff --git a/lib/lanplus/inc/ipmitool/ipmi_sol.h b/lib/lanplus/inc/ipmitool/ipmi_sol.h
new file mode 100644
index 0000000..b4c0f6d
--- /dev/null
+++ b/lib/lanplus/inc/ipmitool/ipmi_sol.h
@@ -0,0 +1,84 @@
+/*
+ * 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.
+ */
+
+#ifndef IPMI_SOL_H
+#define IPMI_SOL_H
+
+#include <ipmitool/ipmi.h>
+
+#define SOL_ESCAPE_CHARACTER_DEFAULT '~'
+#define SOL_KEEPALIVE_TIMEOUT 30
+
+#define IPMI_SOL_SERIAL_ALERT_MASK_SUCCEED 0x08
+#define IPMI_SOL_SERIAL_ALERT_MASK_DEFERRED 0x04
+#define IPMI_SOL_SERIAL_ALERT_MASK_FAIL 0x00
+#define IPMI_SOL_BMC_ASSERTS_CTS_MASK_TRUE 0x00
+#define IPMI_SOL_BMC_ASSERTS_CTS_MASK_FALSE 0x02
+
+
+struct sol_config_parameters {
+ uint8_t set_in_progress;
+ uint8_t enabled;
+ uint8_t force_encryption;
+ uint8_t force_authentication;
+ uint8_t privilege_level;
+ uint8_t character_accumulate_level;
+ uint8_t character_send_threshold;
+ uint8_t retry_count;
+ uint8_t retry_interval;
+ uint8_t non_volatile_bit_rate;
+ uint8_t volatile_bit_rate;
+ uint8_t payload_channel;
+ uint16_t payload_port;
+};
+
+
+/*
+ * The ACTIVATE PAYLOAD command reponse structure
+ * From table 24-2 of the IPMI v2.0 spec
+ */
+struct activate_payload_rsp {
+ uint8_t auxiliary_data[4];
+ uint8_t inbound_payload_size[2]; /* LS byte first */
+ uint8_t outbound_payload_size[2]; /* LS byte first */
+ uint8_t payload_udp_port[2]; /* LS byte first */
+ uint8_t payload_vlan_number[2]; /* LS byte first */
+} __attribute__ ((packed));
+
+
+int ipmi_sol_main(struct ipmi_intf *, int, char **);
+int ipmi_get_sol_info(struct ipmi_intf * intf,
+ uint8_t channel,
+ struct sol_config_parameters * params);
+
+
+#endif /* IPMI_SOL_H */
diff --git a/lib/lanplus/inc/ipmitool/ipmi_strings.h b/lib/lanplus/inc/ipmitool/ipmi_strings.h
new file mode 100644
index 0000000..4116431
--- /dev/null
+++ b/lib/lanplus/inc/ipmitool/ipmi_strings.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind.
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
+ * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE
+ * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
+ * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
+ * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
+ * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
+ * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
+ * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
+ * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#ifndef IPMI_STRINGS_H
+#define IPMI_STRINGS_H
+
+#include <ipmitool/helper.h>
+
+extern const struct valstr completion_code_vals[];
+extern const struct valstr entity_id_vals[];
+extern const struct valstr entity_device_type_vals[];
+extern const struct valstr ipmi_netfn_vals[];
+extern const struct valstr ipmi_channel_activity_type_vals[];
+extern const struct valstr ipmi_privlvl_vals[];
+extern const struct valstr impi_bit_rate_vals[];
+extern const struct valstr ipmi_set_in_progress_vals[];
+extern const struct valstr ipmi_authtype_session_vals[];
+extern const struct valstr ipmi_authtype_vals[];
+extern const struct valstr ipmi_channel_protocol_vals[];
+extern const struct valstr ipmi_channel_medium_vals[];
+extern const struct valstr ipmi_chassis_power_control_vals[];
+extern const struct valstr ipmi_auth_algorithms[];
+extern const struct valstr ipmi_integrity_algorithms[];
+extern const struct valstr ipmi_encryption_algorithms[];
+extern const struct valstr ipmi_oem_info[];
+
+extern const struct oemvalstr ipmi_oem_sdr_type_vals[];
+
+
+
+#endif /*IPMI_STRINGS_H*/
diff --git a/lib/lanplus/inc/ipmitool/ipmi_sunoem.h b/lib/lanplus/inc/ipmitool/ipmi_sunoem.h
new file mode 100644
index 0000000..b2cddd1
--- /dev/null
+++ b/lib/lanplus/inc/ipmitool/ipmi_sunoem.h
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+#ifndef IPMI_SUNOEM_H
+#define IPMI_SUNOEM_H
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <ipmitool/ipmi.h>
+#include <ipmitool/ipmi_sdr.h>
+
+#define IPMI_NETFN_SUNOEM 0x2e
+
+#define IPMI_SUNOEM_SET_SSH_KEY 0x01
+#define IPMI_SUNOEM_DEL_SSH_KEY 0x02
+#define IPMI_SUNOEM_GET_HEALTH_STATUS 0x10
+#define IPMI_SUNOEM_SET_FAN_SPEED 0x20
+#define IPMI_SUNOEM_LED_GET 0x21
+#define IPMI_SUNOEM_LED_SET 0x22
+
+int ipmi_sunoem_main(struct ipmi_intf *, int, char **);
+
+struct ipmi_rs * sunoem_led_get(struct ipmi_intf * intf, struct sdr_record_generic_locator * dev, int ledtype);
+struct ipmi_rs * sunoem_led_set(struct ipmi_intf * intf, struct sdr_record_generic_locator * dev, int ledtype, int ledmode);
+
+#endif /*IPMI_SUNOEM_H*/
+
diff --git a/lib/lanplus/inc/ipmitool/ipmi_tsol.h b/lib/lanplus/inc/ipmitool/ipmi_tsol.h
new file mode 100644
index 0000000..8157cd8
--- /dev/null
+++ b/lib/lanplus/inc/ipmitool/ipmi_tsol.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2005 Tyan Computer Corp. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind.
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
+ * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE
+ * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
+ * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
+ * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
+ * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
+ * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
+ * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
+ * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#ifndef IPMI_TSOL_H
+#define IPMI_TSOL_H
+
+#include <ipmitool/ipmi.h>
+
+#define IPMI_TSOL_CMD_SENDKEY 0x03
+#define IPMI_TSOL_CMD_START 0x06
+#define IPMI_TSOL_CMD_STOP 0x02
+
+#define IPMI_TSOL_DEF_PORT 6230
+
+int ipmi_tsol_main(struct ipmi_intf *, int, char **);
+
+#endif /* IPMI_TSOL_H */
diff --git a/lib/lanplus/inc/ipmitool/ipmi_user.h b/lib/lanplus/inc/ipmitool/ipmi_user.h
new file mode 100644
index 0000000..f8765ff
--- /dev/null
+++ b/lib/lanplus/inc/ipmitool/ipmi_user.h
@@ -0,0 +1,89 @@
+/*
+ * 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.
+ */
+
+#ifndef IPMI_USER_H
+#define IPMI_USER_H
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <ipmitool/ipmi.h>
+
+
+/*
+ * The GET USER ACCESS response from table 22-32 of the IMPI v2.0 spec
+ */
+struct user_access_rsp {
+#if WORDS_BIGENDIAN
+ uint8_t __reserved1 : 2;
+ uint8_t maximum_ids : 6;
+#else
+ uint8_t maximum_ids : 6;
+ uint8_t __reserved1 : 2;
+#endif
+
+#if WORDS_BIGENDIAN
+ uint8_t __reserved2 : 2;
+ uint8_t enabled_user_count : 6;
+#else
+ uint8_t enabled_user_count : 6;
+ uint8_t __reserved2 : 2;
+#endif
+
+#if WORDS_BIGENDIAN
+ uint8_t __reserved3 : 2;
+ uint8_t fixed_name_count : 6;
+#else
+ uint8_t fixed_name_count : 6;
+ uint8_t __reserved3 : 2;
+#endif
+
+#if WORDS_BIGENDIAN
+ uint8_t __reserved4 : 1;
+ uint8_t no_callin_access : 1;
+ uint8_t link_auth_access : 1;
+ uint8_t ipmi_messaging_access : 1;
+ uint8_t channel_privilege_limit : 4;
+#else
+ uint8_t channel_privilege_limit : 4;
+ uint8_t ipmi_messaging_access : 1;
+ uint8_t link_auth_access : 1;
+ uint8_t no_callin_access : 1;
+ uint8_t __reserved4 : 1;
+#endif
+} __attribute__ ((packed));
+
+
+
+int ipmi_user_main(struct ipmi_intf *, int, char **);
+
+#endif /* IPMI_USER_H */
diff --git a/lib/lanplus/inc/ipmitool/log.h b/lib/lanplus/inc/ipmitool/log.h
new file mode 100644
index 0000000..b5dd8c4
--- /dev/null
+++ b/lib/lanplus/inc/ipmitool/log.h
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+
+#ifndef IPMITOOL_LOG_H
+#define IPMITOOL_LOG_H
+
+#ifdef WIN32
+#define LOG_EMERG 0
+#define LOG_ALERT 1
+#define LOG_CRIT 2
+#define LOG_ERR 3
+#define LOG_WARNING 4
+#define LOG_NOTICE 5
+#define LOG_INFO 6
+#define LOG_DEBUG 7
+#else
+#include <syslog.h>
+
+/* sys/syslog.h:
+ * LOG_EMERG 0 system is unusable
+ * LOG_ALERT 1 action must be taken immediately
+ * LOG_CRIT 2 critical conditions
+ * LOG_ERR 3 error conditions
+ * LOG_WARNING 4 warning conditions
+ * LOG_NOTICE 5 normal but significant condition
+ * LOG_INFO 6 informational
+ * LOG_DEBUG 7 debug-level messages
+ */
+#endif
+
+#define LOG_ERROR LOG_ERR
+#define LOG_WARN LOG_WARNING
+
+#define LOG_NAME_DEFAULT "ipmitool"
+#define LOG_MSG_LENGTH 1024
+
+void log_init(const char * name, int isdaemon, int verbose);
+void log_halt(void);
+void log_level_set(int level);
+int log_level_get(void);
+void lprintf(int level, const char * format, ...);
+void lperror(int level, const char * format, ...);
+
+#endif /*IPMITOOL_LOG_H*/
+
diff --git a/lib/lanplus/ipmi_strings.c b/lib/lanplus/ipmi_strings.c
new file mode 100644
index 0000000..1bdeca7
--- /dev/null
+++ b/lib/lanplus/ipmi_strings.c
@@ -0,0 +1,348 @@
+/*
+ * 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.
+ */
+
+#include <stddef.h>
+#include <ipmitool/ipmi_strings.h>
+#include <ipmitool/ipmi_constants.h>
+#include <ipmitool/ipmi_sensor.h>
+#include <ipmitool/ipmi_sel.h> /* for IPMI_OEM */
+
+const struct valstr ipmi_oem_info[] = {
+
+ { IPMI_OEM_UNKNOWN, "Unknown" },
+ { IPMI_OEM_SUN, "Sun Microsystems" },
+ { IPMI_OEM_INTEL, "Intel Corporation" },
+ { IPMI_OEM_TYAN, "Tyan Computer Corporation" },
+ { IPMI_OEM_NEWISYS, "Newisys" },
+ { IPMI_OEM_SUPERMICRO, "Supermicro" },
+ { IPMI_OEM_GOOGLE, "Google" },
+ { IPMI_OEM_KONTRON, "Kontron" },
+ { IPMI_OEM_NOKIA, "Nokia" },
+ { 0xffff , NULL },
+};
+
+const struct oemvalstr ipmi_oem_sdr_type_vals[] = {
+ /* Keep OEM grouped together */
+ { IPMI_OEM_KONTRON , 0xC0 , "OEM Firmware Info" },
+ { IPMI_OEM_KONTRON , 0xC2 , "OEM Init Agent" },
+ { IPMI_OEM_KONTRON , 0xC3 , "OEM IPMBL Link State" },
+ { IPMI_OEM_KONTRON , 0xC4 , "OEM Board Reset" },
+ { IPMI_OEM_KONTRON , 0xC5 , "OEM FRU Information Agent" },
+ { IPMI_OEM_KONTRON , 0xC6 , "OEM POST Value Sensor" },
+ { IPMI_OEM_KONTRON , 0xC7 , "OEM FWUM Status" },
+ { IPMI_OEM_KONTRON , 0xC8 , "OEM Switch Mngt Software Status" },
+
+ { IPMI_OEM_PICMG , 0xF0 , "PICMG FRU Hotswap" },
+ { IPMI_OEM_PICMG , 0xF1 , "PICMG IPMB0 Link State" },
+
+ { 0xffff, 0x00, NULL }
+};
+
+const struct valstr ipmi_netfn_vals[] = {
+ { IPMI_NETFN_CHASSIS, "Chassis" },
+ { IPMI_NETFN_BRIDGE, "Bridge" },
+ { IPMI_NETFN_SE, "SensorEvent" },
+ { IPMI_NETFN_APP, "Application" },
+ { IPMI_NETFN_FIRMWARE, "Firmware" },
+ { IPMI_NETFN_STORAGE, "Storage" },
+ { IPMI_NETFN_TRANSPORT, "Transport" },
+ { 0xff, NULL },
+};
+
+/*
+ * From table 26-4 of the IPMI v2 specification
+ */
+const struct valstr impi_bit_rate_vals[] = {
+ { 0x00, "IPMI-Over-Serial-Setting"}, /* Using the value in the IPMI Over Serial Config */
+ { 0x06, "9.6" },
+ { 0x07, "19.2" },
+ { 0x08, "38.4" },
+ { 0x09, "57.6" },
+ { 0x0A, "115.2" },
+ { 0x00, NULL },
+};
+
+const struct valstr ipmi_channel_activity_type_vals[] = {
+ { 0, "IPMI Messaging session active" },
+ { 1, "Callback Messaging session active" },
+ { 2, "Dial-out Alert active" },
+ { 3, "TAP Page Active" },
+ { 0x00, NULL },
+};
+
+
+const struct valstr ipmi_privlvl_vals[] = {
+ { IPMI_SESSION_PRIV_CALLBACK, "CALLBACK" },
+ { IPMI_SESSION_PRIV_USER, "USER" },
+ { IPMI_SESSION_PRIV_OPERATOR, "OPERATOR" },
+ { IPMI_SESSION_PRIV_ADMIN, "ADMINISTRATOR" },
+ { IPMI_SESSION_PRIV_OEM, "OEM" },
+ { 0xF, "NO ACCESS" },
+ { 0xFF, NULL },
+};
+
+
+const struct valstr ipmi_set_in_progress_vals[] = {
+ { IPMI_SET_IN_PROGRESS_SET_COMPLETE, "set-complete" },
+ { IPMI_SET_IN_PROGRESS_IN_PROGRESS, "set-in-progress" },
+ { IPMI_SET_IN_PROGRESS_COMMIT_WRITE, "commit-write" },
+ { 0, NULL },
+};
+
+
+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" },
+ { 0xFF, NULL },
+};
+
+
+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 },
+};
+
+const struct valstr entity_id_vals[] = {
+ { 0x00, "Unspecified" },
+ { 0x01, "Other" },
+ { 0x02, "Unknown" },
+ { 0x03, "Processor" },
+ { 0x04, "Disk or Disk Bay" },
+ { 0x05, "Peripheral Bay" },
+ { 0x06, "System Management Module" },
+ { 0x07, "System Board" },
+ { 0x08, "Memory Module" },
+ { 0x09, "Processor Module" },
+ { 0x0a, "Power Supply" },
+ { 0x0b, "Add-in Card" },
+ { 0x0c, "Front Panel Board" },
+ { 0x0d, "Back Panel Board" },
+ { 0x0e, "Power System Board" },
+ { 0x0f, "Drive Backplane" },
+ { 0x10, "System Internal Expansion Board" },
+ { 0x11, "Other System Board" },
+ { 0x12, "Processor Board" },
+ { 0x13, "Power Unit" },
+ { 0x14, "Power Module" },
+ { 0x15, "Power Management" },
+ { 0x16, "Chassis Back Panel Board" },
+ { 0x17, "System Chassis" },
+ { 0x18, "Sub-Chassis" },
+ { 0x19, "Other Chassis Board" },
+ { 0x1a, "Disk Drive Bay" },
+ { 0x1b, "Peripheral Bay" },
+ { 0x1c, "Device Bay" },
+ { 0x1d, "Fan Device" },
+ { 0x1e, "Cooling Unit" },
+ { 0x1f, "Cable/Interconnect" },
+ { 0x20, "Memory Device" },
+ { 0x21, "System Management Software" },
+ { 0x22, "BIOS" },
+ { 0x23, "Operating System" },
+ { 0x24, "System Bus" },
+ { 0x25, "Group" },
+ { 0x26, "Remote Management Device" },
+ { 0x27, "External Environment" },
+ { 0x28, "Battery" },
+ { 0x29, "Processing Blade" },
+ { 0x2A, "Connectivity Switch" },
+ { 0x2B, "Processor/Memory Module" },
+ { 0x2C, "I/O Module" },
+ { 0x2D, "Processor/IO Module" },
+ { 0x2E, "Management Controller Firmware" },
+ { 0x2F, "IPMI Channel" },
+ { 0x30, "PCI Bus" },
+ { 0x31, "PCI Express Bus" },
+ { 0x32, "SCSI Bus (parallel)" },
+ { 0x33, "SATA/SAS Bus" },
+ { 0x34, "Processor/Front-Side Bus" },
+ /* PICMG */
+ { 0xA0, "PICMG Front Board" },
+ { 0xC0, "PICMG Rear Transition Module" },
+ { 0xC1, "PICMG AdvancedMC Module" },
+ { 0xF0, "PICMG Shelf Management Controller" },
+ { 0xF1, "PICMG Filtration Unit" },
+ { 0xF2, "PICMG Shelf FRU Information" },
+ { 0xF3, "PICMG Alarm Panel" },
+ { 0x00, NULL },
+};
+
+const struct valstr entity_device_type_vals[] = {
+ { 0x00, "Reserved" },
+ { 0x01, "Reserved" },
+ { 0x02, "DS1624 temperature sensor" },
+ { 0x03, "DS1621 temperature sensor" },
+ { 0x04, "LM75 Temperature Sensor" },
+ { 0x05, "Heceta ASIC" },
+ { 0x06, "Reserved" },
+ { 0x07, "Reserved" },
+ { 0x08, "EEPROM, 24C01" },
+ { 0x09, "EEPROM, 24C02" },
+ { 0x0a, "EEPROM, 24C04" },
+ { 0x0b, "EEPROM, 24C08" },
+ { 0x0c, "EEPROM, 24C16" },
+ { 0x0d, "EEPROM, 24C17" },
+ { 0x0e, "EEPROM, 24C32" },
+ { 0x0f, "EEPROM, 24C64" },
+ { 0x1000, "IPMI FRU Inventory" },
+ { 0x1001, "DIMM Memory ID" },
+ { 0x1002, "IPMI FRU Inventory" },
+ { 0x1003, "System Processor Cartridge FRU" },
+ { 0x11, "Reserved" },
+ { 0x12, "Reserved" },
+ { 0x13, "Reserved" },
+ { 0x14, "PCF 8570 256 byte RAM" },
+ { 0x15, "PCF 8573 clock/calendar" },
+ { 0x16, "PCF 8574A I/O Port" },
+ { 0x17, "PCF 8583 clock/calendar" },
+ { 0x18, "PCF 8593 clock/calendar" },
+ { 0x19, "Clock calendar" },
+ { 0x1a, "PCF 8591 A/D, D/A Converter" },
+ { 0x1b, "I/O Port" },
+ { 0x1c, "A/D Converter" },
+ { 0x1d, "D/A Converter" },
+ { 0x1e, "A/D, D/A Converter" },
+ { 0x1f, "LCD Controller/Driver" },
+ { 0x20, "Core Logic (Chip set) Device" },
+ { 0x21, "LMC6874 Intelligent Battery controller" },
+ { 0x22, "Intelligent Batter controller" },
+ { 0x23, "Combo Management ASIC" },
+ { 0x24, "Maxim 1617 Temperature Sensor" },
+ { 0xbf, "Other/Unspecified" },
+ { 0x00, NULL },
+};
+
+const struct valstr ipmi_channel_protocol_vals[] = {
+ { 0x00, "reserved" },
+ { 0x01, "IPMB-1.0" },
+ { 0x02, "ICMB-1.0" },
+ { 0x03, "reserved" },
+ { 0x04, "IPMI-SMBus" },
+ { 0x05, "KCS" },
+ { 0x06, "SMIC" },
+ { 0x07, "BT-10" },
+ { 0x08, "BT-15" },
+ { 0x09, "TMode" },
+ { 0x1c, "OEM 1" },
+ { 0x1d, "OEM 2" },
+ { 0x1e, "OEM 3" },
+ { 0x1f, "OEM 4" },
+ { 0x00, NULL },
+};
+
+
+const struct valstr ipmi_channel_medium_vals[] = {
+ { IPMI_CHANNEL_MEDIUM_RESERVED, "reserved" },
+ { IPMI_CHANNEL_MEDIUM_IPMB_I2C, "IPMB (I2C)" },
+ { IPMI_CHANNEL_MEDIUM_ICMB_1, "ICMB v1.0" },
+ { IPMI_CHANNEL_MEDIUM_ICMB_09, "ICMB v0.9" },
+ { IPMI_CHANNEL_MEDIUM_LAN, "802.3 LAN" },
+ { IPMI_CHANNEL_MEDIUM_SERIAL, "Serial/Modem" },
+ { IPMI_CHANNEL_MEDIUM_LAN_OTHER,"Other LAN" },
+ { IPMI_CHANNEL_MEDIUM_SMBUS_PCI,"PCI SMBus" },
+ { IPMI_CHANNEL_MEDIUM_SMBUS_1, "SMBus v1.0/v1.1" },
+ { IPMI_CHANNEL_MEDIUM_SMBUS_2, "SMBus v2.0" },
+ { IPMI_CHANNEL_MEDIUM_USB_1, "USB 1.x" },
+ { IPMI_CHANNEL_MEDIUM_USB_2, "USB 2.x" },
+ { IPMI_CHANNEL_MEDIUM_SYSTEM, "System Interface" },
+ { 0x00, NULL },
+};
+
+const struct valstr completion_code_vals[] = {
+ { 0x00, "Command completed normally" },
+ { 0xc0, "Node busy" },
+ { 0xc1, "Invalid command" },
+ { 0xc2, "Invalid command on LUN" },
+ { 0xc3, "Timeout" },
+ { 0xc4, "Out of space" },
+ { 0xc5, "Reservation cancelled or invalid" },
+ { 0xc6, "Request data truncated" },
+ { 0xc7, "Request data length invalid" },
+ { 0xc8, "Request data field length limit exceeded" },
+ { 0xc9, "Parameter out of range" },
+ { 0xca, "Cannot return number of requested data bytes" },
+ { 0xcb, "Requested sensor, data, or record not found" },
+ { 0xcc, "Invalid data field in request" },
+ { 0xcd, "Command illegal for specified sensor or record type" },
+ { 0xce, "Command response could not be provided" },
+ { 0xcf, "Cannot execute duplicated request" },
+ { 0xd0, "SDR Repository in update mode" },
+ { 0xd1, "Device firmeware in update mode" },
+ { 0xd2, "BMC initialization in progress" },
+ { 0xd3, "Destination unavailable" },
+ { 0xd4, "Insufficient privilege level" },
+ { 0xd5, "Command not supported in present state" },
+ { 0xff, "Unspecified error" },
+ { 0x00, NULL }
+};
+
+const struct valstr ipmi_chassis_power_control_vals[] = {
+ { IPMI_CHASSIS_CTL_POWER_DOWN, "Down/Off" },
+ { IPMI_CHASSIS_CTL_POWER_UP, "Up/On" },
+ { IPMI_CHASSIS_CTL_POWER_CYCLE, "Cycle" },
+ { IPMI_CHASSIS_CTL_HARD_RESET, "Reset" },
+ { IPMI_CHASSIS_CTL_PULSE_DIAG, "Diag" },
+ { IPMI_CHASSIS_CTL_ACPI_SOFT, "Soft" },
+ { 0x00, NULL },
+};
+
+const struct valstr ipmi_auth_algorithms[] = {
+ { IPMI_AUTH_RAKP_NONE, "none" },
+ { IPMI_AUTH_RAKP_HMAC_SHA1, "hmac_sha1" },
+ { IPMI_AUTH_RAKP_HMAC_MD5, "hmac_md5" },
+ { IPMI_AUTH_RAKP_HMAC_SHA256, "hmac_sha256" },
+ { 0x00, NULL }
+};
+
+const struct valstr ipmi_integrity_algorithms[] = {
+ { IPMI_INTEGRITY_NONE, "none" },
+ { IPMI_INTEGRITY_HMAC_SHA1_96, "hmac_sha1_96" },
+ { IPMI_INTEGRITY_HMAC_MD5_128, "hmac_md5_128" },
+ { IPMI_INTEGRITY_MD5_128 , "md5_128" },
+ { IPMI_INTEGRITY_HMAC_SHA256_128, "hmac_sha256_128" },
+ { 0x00, NULL }
+};
+
+const struct valstr ipmi_encryption_algorithms[] = {
+ { IPMI_CRYPT_NONE, "none" },
+ { IPMI_CRYPT_AES_CBC_128, "aes_cbc_128" },
+ { IPMI_CRYPT_XRC4_128, "xrc4_128" },
+ { IPMI_CRYPT_XRC4_40, "xrc4_40" },
+ { 0x00, NULL }
+};
diff --git a/lib/lanplus/ipmiplus.mak b/lib/lanplus/ipmiplus.mak
new file mode 100644
index 0000000..9a1435a
--- /dev/null
+++ b/lib/lanplus/ipmiplus.mak
@@ -0,0 +1,67 @@
+# ipmiplus.mak
+# This makefile will build the ipmiutil lib\lanplus directory
+#
+# Make sure to download and build openssl for Windows first
+#
+
+# The ipmiutil lanplus directory
+SRC_D=.
+INC=/I$(SRC_D) /I$(SRC_D)\inc
+O_LIB=lanplus.lib
+
+# Set your compiler options
+CC=cl
+CF_EX=/DWIN32 $(INC) /D_CONSOLE /DNDEBUG /D_CRT_SECURE_NO_DEPRECATE
+# CFLAGS= /MD /W3 /WX /Ox /O2 /Ob2 /Gs0 /GF /Gy /nologo $(CF_EX)
+# CFLAGS= /W3 /Ox /O2 /Ob2 /Gs0 /GF /Gy /nologo $(CF_EX)
+# CFLAGS= /W3 /O2 /Zi /MD /GF /Gy /nologo $(CF_EX)
+# CFLAGS= /W3 /O2 /Zi /MD /nologo $(CF_EX)
+CFLAGS= /W3 /O2 /Zi /MT /nologo $(CF_EX)
+MKLIB=lib
+RM=del
+
+LIB_OBJ = lanplus.obj lanplus_crypt.obj lanplus_crypt_impl.obj \
+ lanplus_dump.obj lanplus_strings.obj helper.obj ipmi_strings.obj
+
+HEADERS =
+
+all: banner $(O_LIB)
+
+banner:
+ @echo Building ipmi lanplus library
+
+install:
+
+clean:
+ $(RM) *.obj 2>NUL
+ $(RM) $(O_LIB) 2>NUL
+
+distclean:
+ $(RM) *.obj 2>NUL
+ $(RM) $(O_LIB) 2>NUL
+ $(RM) *.lib 2>NUL
+
+lanplus.obj: lanplus.c
+ $(CC) /c $(CFLAGS) lanplus.c
+
+lanplus_crypt.obj: lanplus_crypt.c
+ $(CC) /c $(CFLAGS) lanplus_crypt.c
+
+lanplus_crypt_impl.obj: lanplus_crypt_impl.c
+ $(CC) /c $(CFLAGS) lanplus_crypt_impl.c
+
+lanplus_dump.obj: lanplus_dump.c
+ $(CC) /c $(CFLAGS) lanplus_dump.c
+
+lanplus_strings.obj: lanplus_strings.c
+ $(CC) /c $(CFLAGS) lanplus_strings.c
+
+ipmi_strings.obj: ipmi_strings.c
+ $(CC) /c $(CFLAGS) ipmi_strings.c
+
+helper.obj: helper.c
+ $(CC) /c $(CFLAGS) helper.c
+
+$(O_LIB): $(LIB_OBJ)
+ $(MKLIB) /OUT:$(O_LIB) /nologo $(LIB_OBJ)
+
diff --git a/lib/lanplus/lanplus.c b/lib/lanplus/lanplus.c
new file mode 100644
index 0000000..40d3ab4
--- /dev/null
+++ b/lib/lanplus/lanplus.c
@@ -0,0 +1,4036 @@
+/*
+ * 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.
+ */
+/* ARCress, TODO: improve error handling and remove all assert() calls here. */
+
+#ifdef WIN32
+#include <windows.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes-win.h>
+#include <io.h>
+#include <signal.h>
+//#define HAVE_IPV6 1
+#ifdef HAVE_IPV6
+#include <winsock2.h>
+//#include <ws2tcpip.h>
+#else
+#include <winsock.h>
+#endif
+#include <time.h>
+#else
+#include <stdlib.h>
+#include <stdio.h>
+#include <inttypes.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <errno.h>
+#include <unistd.h>
+#include <netdb.h>
+#include <time.h>
+#include <fcntl.h>
+#include <assert.h>
+#endif
+#if defined(LINUX)
+#define HAVE_IPV6 1
+/* TODO: fixups in BSD/Solaris for ipv6 method */
+#endif
+#if defined(MACOS)
+#include <sys/time.h>
+#endif
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <ipmitool/helper.h>
+#include <ipmitool/log.h>
+#include <ipmitool/ipmi.h>
+#include <ipmitool/ipmi_lanp.h>
+#include <ipmitool/ipmi_channel.h>
+#include <ipmitool/ipmi_intf.h>
+#include <ipmitool/ipmi_strings.h>
+#include <ipmitool/bswap.h>
+#include <openssl/rand.h>
+
+#include "lanplus.h"
+#include "lanplus_crypt.h"
+#include "lanplus_crypt_impl.h"
+#include "lanplus_dump.h"
+#include "rmcp.h"
+#include "asf.h"
+
+extern const struct valstr ipmi_rakp_return_codes[];
+extern const struct valstr ipmi_priv_levels[];
+extern const struct valstr ipmi_auth_algorithms[];
+extern const struct valstr ipmi_integrity_algorithms[];
+extern const struct valstr ipmi_encryption_algorithms[];
+
+#if defined(AI_NUMERICSERV)
+static int my_ai_flags = AI_NUMERICSERV; /*0x0400 Dont use name resolution NEW*/
+// static int my_ai_flags = AI_NUMERICHOST; /*0x0004 Dont use name resolution*/
+#else
+#undef HAVE_IPV6
+#endif
+#ifdef HAVE_IPV6
+#define SOCKADDR_T struct sockaddr_storage
+#else
+#define SOCKADDR_T struct sockaddr_in
+#endif
+char lan2_nodename[80] = {0}; /*SZGNOE = 80*/
+static int lan2_timeout = IPMI_LAN_TIMEOUT; /*lanplus.h, usu =1*/
+static int slow_link = 0; /* flag, =1 if slow link, latency > 100ms */
+static int recv_delay = 100; /* delay before recv, usually 100us */
+static struct ipmi_rq_entry * ipmi_req_entries;
+static struct ipmi_rq_entry * ipmi_req_entries_tail;
+
+static int ipmi_lanplus_setup(struct ipmi_intf * intf);
+static int ipmi_lanplus_keepalive(struct ipmi_intf * intf);
+static int ipmi_lan_send_packet(struct ipmi_intf * intf, uint8_t * data, int data_len);
+static struct ipmi_rs * ipmi_lan_recv_packet(struct ipmi_intf * intf);
+static struct ipmi_rs * ipmi_lan_poll_recv(struct ipmi_intf * intf);
+static struct ipmi_rs * ipmi_lanplus_send_ipmi_cmd(struct ipmi_intf * intf, struct ipmi_rq * req);
+static struct ipmi_rs * ipmi_lanplus_send_payload(struct ipmi_intf * intf,
+ struct ipmi_v2_payload * payload);
+static void getIpmiPayloadWireRep(
+ struct ipmi_intf * intf,
+ struct ipmi_v2_payload * payload, /* in */
+ uint8_t * out,
+ struct ipmi_rq * req,
+ uint8_t rq_seq,
+ uint8_t curr_seq);
+static void getSolPayloadWireRep(
+ struct ipmi_intf * intf,
+ uint8_t * msg,
+ struct ipmi_v2_payload * payload);
+static void read_open_session_response(struct ipmi_rs * rsp, int offset);
+static void read_rakp2_message(struct ipmi_rs * rsp, int offset, uint8_t alg);
+static void read_rakp4_message(struct ipmi_rs * rsp, int offset, uint8_t alg);
+static int read_session_data(struct ipmi_rs * rsp, int * offset, struct ipmi_session *s);
+static int read_session_data_v15(struct ipmi_rs * rsp, int * offset, struct ipmi_session *s);
+static int read_session_data_v2x(struct ipmi_rs * rsp, int * offset, struct ipmi_session *s);
+static void read_ipmi_response(struct ipmi_rs * rsp, int * offset);
+static void read_sol_packet(struct ipmi_rs * rsp, int * offset);
+static struct ipmi_rs * ipmi_lanplus_recv_sol(struct ipmi_intf * intf);
+static struct ipmi_rs * ipmi_lanplus_send_sol( struct ipmi_intf * intf,
+ void * payload);
+static int check_sol_packet_for_new_data(
+ struct ipmi_intf * intf,
+ struct ipmi_rs *rsp);
+static void ack_sol_packet(
+ struct ipmi_intf * intf,
+ struct ipmi_rs * rsp);
+
+static uint8_t bridgePossible = 0;
+
+#if defined(WIN32) || defined(SOLARIS)
+struct ipmi_intf ipmi_lanplus_intf;
+void ipmilanplus_init(struct ipmi_intf *intf)
+{
+ strcpy(intf->name,"lanplus");
+ intf->setup = ipmi_lanplus_setup;
+ intf->open = ipmi_lanplus_open;
+ intf->close = ipmi_lanplus_close;
+ intf->sendrecv = ipmi_lanplus_send_ipmi_cmd;
+ intf->recv_sol = ipmi_lanplus_recv_sol;
+ intf->send_sol = ipmi_lanplus_send_sol;
+ intf->keepalive = ipmi_lanplus_keepalive;
+ intf->target_addr = IPMI_BMC_SLAVE_ADDR; /*0x20*/
+}
+#else
+struct ipmi_intf ipmi_lanplus_intf = {
+ name: "lanplus",
+ desc: "IPMI v2.0 RMCP+ LAN Interface",
+ setup: ipmi_lanplus_setup,
+ open: ipmi_lanplus_open,
+ close: ipmi_lanplus_close,
+ sendrecv: ipmi_lanplus_send_ipmi_cmd,
+ recv_sol: ipmi_lanplus_recv_sol,
+ send_sol: ipmi_lanplus_send_sol,
+ keepalive: ipmi_lanplus_keepalive,
+ target_addr: IPMI_BMC_SLAVE_ADDR,
+};
+void ipmilanplus_init(struct ipmi_intf *intf)
+{
+ return;
+}
+#endif
+
+
+extern int verbose;
+
+
+#ifdef WIN32
+WSADATA lan2_ws;
+
+#define assert(N) /*empty*/
+#endif
+
+static
+void lan2_usleep(int s, int u) /*lanplus copy of os_usleep*/
+{
+
+ if (s == 0) {
+#ifdef WIN32
+ if (u >= 1000) Sleep(u/1000);
+ } else {
+ Sleep(s * 1000);
+#else
+ usleep(u);
+ } else {
+ sleep(s);
+#endif
+ }
+}
+
+void show_lasterr(char *tag)
+{
+#ifdef WIN32
+ int rv = 0;
+ rv = WSAGetLastError();
+ fprintf(stderr,"%s LastError = %d\n",tag,rv);
+#else
+ fprintf(stderr,"%s errno = %d\n",tag,errno);
+#endif
+}
+
+/*
+ * lanplus_get_requested_ciphers
+ *
+ * Set the authentication, integrity and encryption algorithms based
+ * on the cipher suite ID. See table 22-19 in the IPMIv2 spec for the
+ * source of this information.
+ *
+ * param cipher_suite_id [in]
+ * param auth_alg [out]
+ * param integrity_alg [out]
+ * param crypt_alg [out]
+ *
+ * returns 0 on success
+ * 1 on failure
+ */
+int lanplus_get_requested_ciphers(int cipher_suite_id,
+ uint8_t * auth_alg,
+ uint8_t * integrity_alg,
+ uint8_t * crypt_alg)
+{
+ if ((cipher_suite_id < 0) || (cipher_suite_id > 17))
+ return 1;
+
+ /* See table 22-19 for the source of the statement */
+ switch (cipher_suite_id)
+ {
+ case 0:
+ *auth_alg = IPMI_AUTH_RAKP_NONE;
+ *integrity_alg = IPMI_INTEGRITY_NONE;
+ *crypt_alg = IPMI_CRYPT_NONE;
+ break;
+ case 1:
+ *auth_alg = IPMI_AUTH_RAKP_HMAC_SHA1;
+ *integrity_alg = IPMI_INTEGRITY_NONE;
+ *crypt_alg = IPMI_CRYPT_NONE;
+ break;
+ case 2:
+ *auth_alg = IPMI_AUTH_RAKP_HMAC_SHA1;
+ *integrity_alg = IPMI_INTEGRITY_HMAC_SHA1_96;
+ *crypt_alg = IPMI_CRYPT_NONE;
+ break;
+ case 3:
+ *auth_alg = IPMI_AUTH_RAKP_HMAC_SHA1;
+ *integrity_alg = IPMI_INTEGRITY_HMAC_SHA1_96;
+ *crypt_alg = IPMI_CRYPT_AES_CBC_128;
+ break;
+ case 4:
+ *auth_alg = IPMI_AUTH_RAKP_HMAC_SHA1;
+ *integrity_alg = IPMI_INTEGRITY_HMAC_SHA1_96;
+ *crypt_alg = IPMI_CRYPT_XRC4_128;
+ break;
+ case 5:
+ *auth_alg = IPMI_AUTH_RAKP_HMAC_SHA1;
+ *integrity_alg = IPMI_INTEGRITY_HMAC_SHA1_96;
+ *crypt_alg = IPMI_CRYPT_XRC4_40;
+ break;
+ case 6:
+ *auth_alg = IPMI_AUTH_RAKP_HMAC_MD5;
+ *integrity_alg = IPMI_INTEGRITY_NONE;
+ *crypt_alg = IPMI_CRYPT_NONE;
+ break;
+ case 7:
+ *auth_alg = IPMI_AUTH_RAKP_HMAC_MD5;
+ *integrity_alg = IPMI_INTEGRITY_HMAC_MD5_128;
+ *crypt_alg = IPMI_CRYPT_NONE;
+ break;
+ case 8:
+ *auth_alg = IPMI_AUTH_RAKP_HMAC_MD5;
+ *integrity_alg = IPMI_INTEGRITY_HMAC_MD5_128;
+ *crypt_alg = IPMI_CRYPT_AES_CBC_128;
+ break;
+ case 9:
+ *auth_alg = IPMI_AUTH_RAKP_HMAC_MD5;
+ *integrity_alg = IPMI_INTEGRITY_HMAC_MD5_128;
+ *crypt_alg = IPMI_CRYPT_XRC4_128;
+ break;
+ case 10:
+ *auth_alg = IPMI_AUTH_RAKP_HMAC_MD5;
+ *integrity_alg = IPMI_INTEGRITY_HMAC_MD5_128;
+ *crypt_alg = IPMI_CRYPT_XRC4_40;
+ break;
+ case 11:
+ *auth_alg = IPMI_AUTH_RAKP_HMAC_MD5;
+ *integrity_alg = IPMI_INTEGRITY_MD5_128;
+ *crypt_alg = IPMI_CRYPT_NONE;
+ break;
+ case 12:
+ *auth_alg = IPMI_AUTH_RAKP_HMAC_MD5;
+ *integrity_alg = IPMI_INTEGRITY_MD5_128;
+ *crypt_alg = IPMI_CRYPT_AES_CBC_128;
+ break;
+ case 13:
+ *auth_alg = IPMI_AUTH_RAKP_HMAC_MD5;
+ *integrity_alg = IPMI_INTEGRITY_MD5_128;
+ *crypt_alg = IPMI_CRYPT_XRC4_128;
+ break;
+ case 14:
+ *auth_alg = IPMI_AUTH_RAKP_HMAC_MD5;
+ *integrity_alg = IPMI_INTEGRITY_MD5_128;
+ *crypt_alg = IPMI_CRYPT_XRC4_40;
+ break;
+#if 0
+ case 15: // Note: Cipher Suite ID not (yet) confirmed in IPMI Spec or Errata 4
+ *auth_alg = IPMI_AUTH_RAKP_HMAC_SHA256;
+ *integrity_alg = IPMI_INTEGRITY_NONE;
+ *crypt_alg = IPMI_CRYPT_NONE;
+ break;
+ case 16: // Note: Cipher Suite ID not (yet) confirmed in IPMI Spec or Errata 4
+ *auth_alg = IPMI_AUTH_RAKP_HMAC_SHA256;
+ *integrity_alg = IPMI_INTEGRITY_HMAC_SHA256_128;
+ *crypt_alg = IPMI_CRYPT_NONE;
+ break;
+#endif
+#ifdef HAVE_SHA256
+ /* based on an MD5_SHA256 patch from Holger Liebig */
+ case 17: // Note: Cipher Suite Id from DCMI 1.1 Spec
+ *auth_alg = IPMI_AUTH_RAKP_HMAC_SHA256;
+ *integrity_alg = IPMI_INTEGRITY_HMAC_SHA256_128;
+ *crypt_alg = IPMI_CRYPT_AES_CBC_128;
+ break;
+#endif
+ default:
+ lprintf(LOG_ERR, "invalid cipher suite id %d",cipher_suite_id);
+ return 1;
+ break;
+
+ }
+
+ return 0;
+}
+
+
+
+/*
+ * Reverse the order of arbitrarily long strings of bytes
+ */
+void lanplus_swap(
+ uint8_t * buffer,
+ int length)
+{
+ int i;
+ uint8_t temp;
+
+ for (i =0; i < length/2; ++i)
+ {
+ temp = buffer[i];
+ buffer[i] = buffer[length - 1 - i];
+ buffer[length - 1 - i] = temp;
+ }
+}
+
+void lanplus_set_recvdelay( int delay)
+{
+ /* set the delay between send & recv in usec, default = 100us */
+ recv_delay = delay;
+ if (delay > 100) {
+ slow_link = 1;
+ lan2_timeout = 2;
+ }
+}
+
+
+static const struct valstr plus_payload_types_vals[] = {
+ { IPMI_PAYLOAD_TYPE_IPMI, "IPMI (0)" }, // IPMI Message
+ { IPMI_PAYLOAD_TYPE_SOL, "SOL (1)" }, // SOL (Serial over LAN)
+ { IPMI_PAYLOAD_TYPE_OEM, "OEM (2)" }, // OEM Explicid
+
+ { IPMI_PAYLOAD_TYPE_RMCP_OPEN_REQUEST, "OpenSession Req (0x10)" },
+ { IPMI_PAYLOAD_TYPE_RMCP_OPEN_RESPONSE,"OpenSession Resp (0x11)" },
+ { IPMI_PAYLOAD_TYPE_RAKP_1, "RAKP1 (0x12)" },
+ { IPMI_PAYLOAD_TYPE_RAKP_2, "RAKP2 (0x13)" },
+ { IPMI_PAYLOAD_TYPE_RAKP_3, "RAKP3 (0x14)" },
+ { IPMI_PAYLOAD_TYPE_RAKP_4, "RAKP4 (0x15)" },
+ { 0x00, NULL },
+};
+
+
+static struct ipmi_rq_entry *
+ipmi_req_add_entry(struct ipmi_intf * intf, struct ipmi_rq * req, uint8_t req_seq)
+{
+ struct ipmi_rq_entry * e;
+
+ e = malloc(sizeof(struct ipmi_rq_entry));
+ if (e == NULL) {
+ lprintf(LOG_ERR, "lanplus: malloc failure");
+ return NULL;
+ }
+
+ memset(e, 0, sizeof(struct ipmi_rq_entry));
+ memcpy(&e->req, req, sizeof(struct ipmi_rq));
+
+ e->intf = intf;
+ e->rq_seq = req_seq;
+
+ if (ipmi_req_entries == NULL)
+ ipmi_req_entries = e;
+ else
+ ipmi_req_entries_tail->next = e;
+
+ ipmi_req_entries_tail = e;
+ lprintf(LOG_DEBUG+3, "added list entry seq=0x%02x cmd=0x%02x",
+ e->rq_seq, e->req.msg.cmd);
+ return e;
+}
+
+
+static struct ipmi_rq_entry *
+ipmi_req_lookup_entry(uint8_t seq, uint8_t cmd)
+{
+ struct ipmi_rq_entry * e = ipmi_req_entries;
+ while (e && (e->rq_seq != seq || e->req.msg.cmd != cmd)) {
+ if (e == e->next)
+ return NULL;
+ e = e->next;
+ }
+ return e;
+}
+
+static void
+ipmi_req_remove_entry(uint8_t seq, uint8_t cmd)
+{
+ struct ipmi_rq_entry * p, * e, *saved_next_entry;
+
+ e = p = ipmi_req_entries;
+
+ while (e && (e->rq_seq != seq || e->req.msg.cmd != cmd)) {
+ p = e;
+ e = e->next;
+ }
+ if (e) {
+ lprintf(LOG_DEBUG+3, "removed list entry seq=0x%02x cmd=0x%02x",
+ seq, cmd);
+ saved_next_entry = e->next;
+ p->next = (p->next == e->next) ? NULL : e->next;
+ /* If entry being removed is first in list, fix up list head */
+ if (ipmi_req_entries == e) {
+ if (ipmi_req_entries != p)
+ ipmi_req_entries = p;
+ else
+ ipmi_req_entries = saved_next_entry;
+ }
+ /* If entry being removed is last in list, fix up list tail */
+ if (ipmi_req_entries_tail == e) {
+ if (ipmi_req_entries_tail != p)
+ ipmi_req_entries_tail = p;
+ else
+ ipmi_req_entries_tail = NULL;
+ }
+
+ if (e->msg_data)
+ free(e->msg_data);
+ free(e);
+ }
+}
+
+static void
+ipmi_req_clear_entries(void)
+{
+ struct ipmi_rq_entry * p, * e;
+
+ e = ipmi_req_entries;
+ while (e) {
+ lprintf(LOG_DEBUG+3, "cleared list entry seq=0x%02x cmd=0x%02x",
+ e->rq_seq, e->req.msg.cmd);
+ p = e->next;
+ if (e->msg_data) free(e->msg_data); /*added in v2.8.5*/
+ free(e);
+ e = p;
+ }
+ ipmi_req_entries = NULL;
+}
+
+
+int
+ipmi_lan_send_packet(
+ struct ipmi_intf * intf,
+ uint8_t * data, int
+ data_len)
+{
+ if (verbose >= 5)
+ printbuf(data, data_len, ">> sending packet");
+
+ return send(intf->fd, data, data_len, 0);
+}
+
+
+
+struct ipmi_rs *
+ipmi_lan_recv_packet(struct ipmi_intf * intf)
+{
+ static struct ipmi_rs rsp;
+ fd_set read_set, err_set;
+ struct timeval tmout;
+ int ret = 0;
+ int er,rd;
+
+ FD_ZERO(&read_set);
+ FD_SET(intf->fd, &read_set);
+
+ FD_ZERO(&err_set);
+ FD_SET(intf->fd, &err_set);
+
+ tmout.tv_sec = intf->session->timeout;
+ tmout.tv_usec = 0;
+ ret = select((int)(intf->fd + 1), &read_set, NULL, &err_set, &tmout);
+ er = FD_ISSET(intf->fd, &err_set);
+ rd = FD_ISSET(intf->fd, &read_set);
+ if (ret < 0 || er || !rd) {
+ if (verbose >= 5)
+ lprintf(LOG_INFO, "select1 error ret=%d, err=%d read=%d",
+ ret,er,rd);
+ return NULL;
+ }
+
+ /* the first read may return ECONNREFUSED because the rmcp ping
+ * packet--sent to UDP port 623--will be processed by both the
+ * BMC and the OS.
+ *
+ * The problem with this is that the ECONNREFUSED takes
+ * priority over any other received datagram; that means that
+ * the Connection Refused shows up _before_ the response packet,
+ * regardless of the order they were sent out. (unless the
+ * response is read before the connection refused is returned)
+ */
+#ifdef WIN32
+ ret = recv(intf->fd, &rsp.data[0], IPMI_BUF_SIZE, 0);
+#else
+ ret = recv(intf->fd, &rsp.data, IPMI_BUF_SIZE, 0);
+#endif
+
+ if (ret < 0) {
+ if (verbose >= 5) lprintf(LOG_INFO, "recv1 ret=%d",ret);
+ FD_ZERO(&read_set);
+ FD_SET(intf->fd, &read_set);
+
+ FD_ZERO(&err_set);
+ FD_SET(intf->fd, &err_set);
+
+ tmout.tv_sec = intf->session->timeout;
+ tmout.tv_usec = 0;
+
+ ret = select((int)(intf->fd + 1), &read_set, NULL, &err_set, &tmout);
+ if (ret < 0) {
+ if (FD_ISSET(intf->fd, &err_set) || !FD_ISSET(intf->fd, &read_set)) {
+ if (verbose >= 5)
+ lprintf(LOG_INFO,"select2 error ret=%d",ret);
+ return NULL;
+ }
+
+#ifdef WIN32
+ ret = recv(intf->fd, &rsp.data[0], IPMI_BUF_SIZE, 0);
+#else
+ ret = recv(intf->fd, &rsp.data, IPMI_BUF_SIZE, 0);
+#endif
+ if (ret < 0) {
+ if (verbose >= 5)
+ lprintf(LOG_INFO, "recv2 ret=%d",ret);
+ return NULL;
+ }
+ }
+ }
+
+ if (ret == 0) {
+ if (verbose >= 5) lprintf(LOG_INFO, "recv ret==0");
+ return NULL;
+ }
+
+ rsp.data[ret] = '\0';
+ rsp.data_len = ret;
+
+ if (verbose >= 5)
+ printbuf(rsp.data, rsp.data_len, "<< received packet");
+
+ return &rsp;
+}
+
+
+
+/*
+ * parse response RMCP "pong" packet
+ *
+ * return -1 if ping response not received
+ * returns 0 if IPMI is NOT supported
+ * returns 1 if IPMI is supported
+ *
+ * udp.source = 0x026f // RMCP_UDP_PORT
+ * udp.dest = ? // udp.source from rmcp-ping
+ * udp.len = ?
+ * udp.check = ?
+ * rmcp.ver = 0x06 // RMCP Version 1.0
+ * rmcp.__res = 0x00 // RESERVED
+ * rmcp.seq = 0xff // no RMCP ACK
+ * rmcp.class = 0x06 // RMCP_CLASS_ASF
+ * asf.iana = 0x000011be // ASF_RMCP_IANA
+ * asf.type = 0x40 // ASF_TYPE_PONG
+ * asf.tag = ? // asf.tag from rmcp-ping
+ * asf.__res = 0x00 // RESERVED
+ * asf.len = 0x10 // 16 bytes
+ * asf.data[3:0]= 0x000011be // IANA# = RMCP_ASF_IANA if no OEM
+ * asf.data[7:4]= 0x00000000 // OEM-defined (not for IPMI)
+ * asf.data[8] = 0x81 // supported entities
+ * // [7]=IPMI [6:4]=RES [3:0]=ASF_1.0
+ * asf.data[9] = 0x00 // supported interactions (reserved)
+ * asf.data[f:a]= 0x000000000000
+ */
+static int
+ipmi_handle_pong(struct ipmi_intf * intf, struct ipmi_rs * rsp)
+{
+ struct rmcp_pong {
+ struct rmcp_hdr rmcp;
+ struct asf_hdr asf;
+ uint32_t iana;
+ uint32_t oem;
+ uint8_t sup_entities;
+ uint8_t sup_interact;
+ uint8_t reserved[6];
+ } * pong;
+
+ if (!rsp)
+ return -1;
+
+ pong = (struct rmcp_pong *)rsp->data;
+
+ if (verbose)
+ printf("Received IPMI/RMCP response packet: "
+ "IPMI%s Supported\n",
+ (pong->sup_entities & 0x80) ? "" : " NOT");
+
+ if (verbose > 1)
+ printf(" ASF Version %s\n"
+ " RMCP Version %s\n"
+ " RMCP Sequence %d\n"
+ " IANA Enterprise %lu\n\n",
+ (pong->sup_entities & 0x01) ? "1.0" : "unknown",
+ (pong->rmcp.ver == 6) ? "1.0" : "unknown",
+ pong->rmcp.seq,
+ (unsigned long)ntohl(pong->iana));
+
+ return (pong->sup_entities & 0x80) ? 1 : 0;
+}
+
+
+/* build and send RMCP presence ping packet
+ *
+ * RMCP ping
+ *
+ * udp.source = ?
+ * udp.dest = 0x026f // RMCP_UDP_PORT
+ * udp.len = ?
+ * udp.check = ?
+ * rmcp.ver = 0x06 // RMCP Version 1.0
+ * rmcp.__res = 0x00 // RESERVED
+ * rmcp.seq = 0xff // no RMCP ACK
+ * rmcp.class = 0x06 // RMCP_CLASS_ASF
+ * asf.iana = 0x000011be // ASF_RMCP_IANA
+ * asf.type = 0x80 // ASF_TYPE_PING
+ * asf.tag = ? // ASF sequence number
+ * asf.__res = 0x00 // RESERVED
+ * asf.len = 0x00
+ *
+ */
+int
+ipmiv2_lan_ping(struct ipmi_intf * intf)
+{
+ uint8_t * data;
+ int rv;
+#if defined(WIN32) || defined(SOLARIS)
+ struct asf_hdr asf_ping;
+ struct rmcp_hdr rmcp_ping;
+ int len = sizeof(rmcp_ping) + sizeof(asf_ping);
+
+ asf_ping.iana = htonl(ASF_RMCP_IANA);
+ asf_ping.type = ASF_TYPE_PING;
+ rmcp_ping.ver = RMCP_VERSION_1;
+ rmcp_ping.__rsvd = 0;
+ rmcp_ping.class = RMCP_CLASS_ASF;
+ rmcp_ping.seq = 0xff;
+#else
+ struct asf_hdr asf_ping = {
+ .iana = htonl(ASF_RMCP_IANA),
+ .type = ASF_TYPE_PING,
+ };
+ struct rmcp_hdr rmcp_ping = {
+ .ver = RMCP_VERSION_1,
+ .__rsvd = 0,
+ .class = RMCP_CLASS_ASF,
+ .seq = 0xff,
+ };
+ int len = sizeof(rmcp_ping) + sizeof(asf_ping);
+#endif
+
+ data = malloc(len);
+ if (data == NULL) {
+ lprintf(LOG_ERR, "lanplus: malloc failure");
+ return -1;
+ }
+ memset(data, 0, len);
+ memcpy(data, &rmcp_ping, sizeof(rmcp_ping));
+ memcpy(data+sizeof(rmcp_ping), &asf_ping, sizeof(asf_ping));
+
+ lprintf(LOG_DEBUG, "Sending IPMI/RMCP presence ping packet");
+
+ rv = ipmi_lan_send_packet(intf, data, len);
+
+ free(data);
+
+ if (rv < 0) {
+ lprintf(LOG_ERR, "Unable to send IPMI presence ping packet");
+ return -1;
+ }
+
+ if (ipmi_lan_poll_recv(intf) == 0) /*NULL rsp*/
+ return 0;
+
+ return 1;
+}
+
+
+/**
+ *
+ * ipmi_lan_poll_recv
+ *
+ * Receive whatever comes back. Ignore received packets that don't correspond
+ * to a request we've sent.
+ *
+ * Returns: the ipmi_rs packet describing the/a reponse we expect.
+ */
+static struct ipmi_rs *
+ipmi_lan_poll_recv(struct ipmi_intf * intf)
+{
+ struct rmcp_hdr rmcp_rsp;
+ struct ipmi_rs * rsp;
+ struct ipmi_session * session = intf->session;
+ int offset, rv;
+ uint16_t payload_size;
+ uint8_t ourAddress = (uint8_t)intf->my_addr;
+
+ if (ourAddress == 0) {
+ ourAddress = IPMI_BMC_SLAVE_ADDR;
+ }
+
+ rsp = ipmi_lan_recv_packet(intf);
+
+ /*
+ * Not positive why we're looping. Do we sometimes get stuff we don't
+ * expect?
+ */
+ while (rsp != NULL) {
+
+ /* parse response headers */
+ memcpy(&rmcp_rsp, rsp->data, 4);
+
+ if (rmcp_rsp.class == RMCP_CLASS_ASF) {
+ /* might be ping response packet */
+ rv = ipmi_handle_pong(intf, rsp);
+ return (rv <= 0) ? NULL : rsp;
+ }
+
+ if (rmcp_rsp.class != RMCP_CLASS_IPMI) {
+ lprintf(LOG_DEBUG, "Invalid RMCP class: %x",
+ rmcp_rsp.class);
+ rsp = ipmi_lan_recv_packet(intf);
+ continue;
+ }
+
+
+ /*
+ * The authtype / payload type determines what we are receiving
+ */
+ offset = 4;
+
+
+ /*--------------------------------------------------------------
+ *
+ * The current packet could be one of several things:
+ *
+ * 1) An IPMI 1.5 packet (the response to our GET CHANNEL
+ * AUTHENTICATION CAPABILITIES request)
+ * 2) An RMCP+ message with an IPMI response payload
+ * 3) AN RMCP+ open session response
+ * 4) An RAKP-2 message (response to an RAKP 1 message)
+ * 5) An RAKP-4 message (response to an RAKP 3 message)
+ * 6) A Serial Over LAN packet
+ * 7) An Invalid packet (one that doesn't match a request)
+ * -------------------------------------------------------------
+ */
+ rv = read_session_data(rsp, &offset, intf->session);
+ if (rv != 0) return(NULL);
+
+ lprintf(LOG_INFO, "rsp session_id=%08lx session_seq=%08lx",
+ (long)rsp->session.id, (long)rsp->session.seq);
+
+ if (lanplus_has_valid_auth_code(rsp, intf->session) == 0)
+ {
+ lprintf(LOG_ERR, "ERROR: Received message with invalid authcode!");
+ return(NULL); /*was ipmi_lan_recv_packet, assert*/
+ }
+
+ if ((session->v2_data.session_state == LANPLUS_STATE_ACTIVE) &&
+ (rsp->session.authtype == IPMI_SESSION_AUTHTYPE_RMCP_PLUS) &&
+ (rsp->session.bEncrypted))
+
+ {
+ lanplus_decrypt_payload(session->v2_data.crypt_alg,
+ session->v2_data.k2,
+ rsp->data + offset,
+ rsp->session.msglen,
+ rsp->data + offset,
+ &payload_size);
+ }
+ else
+ payload_size = rsp->session.msglen;
+
+ /*
+ * Handle IPMI responses (case #1 and #2) -- all IPMI reponses
+ */
+ if (rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_IPMI)
+ {
+ struct ipmi_rq_entry * entry;
+ int payload_start = offset;
+ int extra_data_length;
+ read_ipmi_response(rsp, &offset);
+
+ lprintf(LOG_DEBUG+1, "<< IPMI Response Session Header");
+ lprintf(LOG_DEBUG+1, "<< Authtype : %s",
+ val2str(rsp->session.authtype, ipmi_authtype_session_vals));
+ lprintf(LOG_DEBUG+1, "<< Payload type : %s",
+ val2str(rsp->session.payloadtype, plus_payload_types_vals));
+ lprintf(LOG_DEBUG+1, "<< Session ID : 0x%08lx",
+ (long)rsp->session.id);
+ lprintf(LOG_DEBUG+1, "<< Sequence : 0x%08lx",
+ (long)rsp->session.seq);
+ lprintf(LOG_DEBUG+1, "<< IPMI Msg/Payload Length : %d",
+ rsp->session.msglen);
+ lprintf(LOG_DEBUG+1, "<< IPMI Response Message Header");
+ lprintf(LOG_DEBUG+1, "<< Rq Addr : %02x",
+ rsp->payload.ipmi_response.rq_addr);
+ lprintf(LOG_DEBUG+1, "<< NetFn : %02x",
+ rsp->payload.ipmi_response.netfn);
+ lprintf(LOG_DEBUG+1, "<< Rq LUN : %01x",
+ rsp->payload.ipmi_response.rq_lun);
+ lprintf(LOG_DEBUG+1, "<< Rs Addr : %02x",
+ rsp->payload.ipmi_response.rs_addr);
+ lprintf(LOG_DEBUG+1, "<< Rq Seq : %02x",
+ rsp->payload.ipmi_response.rq_seq);
+ lprintf(LOG_DEBUG+1, "<< Rs Lun : %01x",
+ rsp->payload.ipmi_response.rs_lun);
+ lprintf(LOG_DEBUG+1, "<< Command : %02x",
+ rsp->payload.ipmi_response.cmd);
+ lprintf(LOG_DEBUG+1, "<< Compl Code : 0x%02x",
+ rsp->ccode);
+
+ /* Are we expecting this packet? */
+ entry = ipmi_req_lookup_entry(rsp->payload.ipmi_response.rq_seq,
+ rsp->payload.ipmi_response.cmd);
+ if (entry != NULL) {
+ lprintf(LOG_DEBUG+2, "IPMI Request Match found");
+ if ( intf->target_addr != intf->my_addr &&
+ bridgePossible && rsp->data_len &&
+ rsp->payload.ipmi_response.cmd == 0x34 )
+ {
+ /* Check completion code */
+ if (rsp->data[offset-1] == 0)
+ {
+ lprintf(LOG_DEBUG,
+ "Bridged command answer,"
+ " waiting for next answer... ");
+ ipmi_req_remove_entry(
+ rsp->payload.ipmi_response.rq_seq,
+ rsp->payload.ipmi_response.cmd);
+ return(ipmi_lan_poll_recv(intf));
+ } else {
+ lprintf(LOG_DEBUG, "WARNING: Bridged"
+ "cmd ccode = 0x%02x",
+ rsp->data[offset-1]);
+ }
+
+ if (rsp->data_len &&
+ rsp->payload.ipmi_response.cmd== 0x34) {
+
+ memcpy(rsp->data, &rsp->data[offset],
+ (rsp->data_len-offset));
+ printbuf( &rsp->data[offset],
+ (rsp->data_len-offset),
+ "bridge command response");
+ }
+ }
+ ipmi_req_remove_entry(
+ rsp->payload.ipmi_response.rq_seq,
+ rsp->payload.ipmi_response.cmd);
+
+ } else {
+ lprintf(LOG_INFO, "IPMI Request Match NOT FOUND");
+ rsp = ipmi_lan_recv_packet(intf);
+ continue;
+ }
+
+ /*
+ * Good packet. Shift response data to start of array.
+ * rsp->data becomes the variable length IPMI response data
+ * rsp->data_len becomes the length of that data
+ */
+ extra_data_length = payload_size - (offset - payload_start) - 1;
+ if (rsp != NULL && extra_data_length)
+ {
+ rsp->data_len = extra_data_length;
+ memmove(rsp->data, rsp->data + offset, extra_data_length);
+ }
+ else
+ rsp->data_len = 0;
+
+ break;
+ }
+
+
+ /*
+ * Open Response
+ */
+ else if (rsp->session.payloadtype ==
+ IPMI_PAYLOAD_TYPE_RMCP_OPEN_RESPONSE)
+ {
+ if (session->v2_data.session_state !=
+ LANPLUS_STATE_OPEN_SESSION_SENT)
+ {
+ lprintf(LOG_ERR, "Error: Received an Unexpected Open Session "
+ "Response");
+ rsp = ipmi_lan_recv_packet(intf);
+ continue;
+ }
+
+ read_open_session_response(rsp, offset);
+ break;
+ }
+
+
+ /*
+ * RAKP 2
+ */
+ else if (rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_RAKP_2)
+ {
+ if (session->v2_data.session_state != LANPLUS_STATE_RAKP_1_SENT)
+ {
+ lprintf(LOG_ERR, "Error: Received an Unexpected RAKP 2 message");
+ rsp = ipmi_lan_recv_packet(intf);
+ continue;
+ }
+
+ read_rakp2_message(rsp, offset, session->v2_data.auth_alg);
+ break;
+ }
+
+
+ /*
+ * RAKP 4
+ */
+ else if (rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_RAKP_4)
+ {
+ if (session->v2_data.session_state != LANPLUS_STATE_RAKP_3_SENT)
+ {
+ lprintf(LOG_ERR, "Error: Received an Unexpected RAKP 4 message");
+ rsp = ipmi_lan_recv_packet(intf);
+ continue;
+ }
+
+ read_rakp4_message(rsp, offset, session->v2_data.auth_alg);
+ break;
+ }
+
+
+ /*
+ * SOL
+ */
+ else if (rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_SOL)
+ {
+ int payload_start = offset;
+ int extra_data_length;
+
+ if (session->v2_data.session_state != LANPLUS_STATE_ACTIVE)
+ {
+ lprintf(LOG_ERR, "Error: Received an Unexpected SOL packet");
+ rsp = ipmi_lan_recv_packet(intf);
+ continue;
+ }
+
+ read_sol_packet(rsp, &offset);
+ extra_data_length = payload_size - (offset - payload_start);
+ if (rsp && extra_data_length)
+ {
+ rsp->data_len = extra_data_length;
+ memmove(rsp->data, rsp->data + offset, extra_data_length);
+ }
+ else
+ rsp->data_len = 0;
+
+ break;
+ }
+
+ else
+ {
+ lprintf(LOG_ERR, "Invalid RMCP+ payload type : 0x%x",
+ rsp->session.payloadtype);
+ return(NULL); //assert(0);
+ }
+ }
+
+ return rsp;
+}
+
+
+
+/*
+ * read_open_session_reponse
+ *
+ * Initialize the ipmi_rs from the IPMI 2.x open session response data.
+ *
+ * The offset should point to the first byte of the the Open Session Response
+ * payload when this function is called.
+ *
+ * param rsp [in/out] reading from the data and writing to the open_session_response
+ * section
+ * param offset [in] tells us where the Open Session Response payload starts
+ *
+ * returns 0 on success, 1 on error
+ */
+void
+read_open_session_response(struct ipmi_rs * rsp, int offset)
+{
+ memset(&rsp->payload.open_session_response, 0,
+ sizeof(rsp->payload.open_session_response));
+
+ /* Message tag */
+ rsp->payload.open_session_response.message_tag = rsp->data[offset];
+
+ /* RAKP reponse code */
+ rsp->payload.open_session_response.rakp_return_code = rsp->data[offset + 1];
+
+ /* Maximum privilege level */
+ rsp->payload.open_session_response.max_priv_level = rsp->data[offset + 2];
+
+ /*** offset + 3 is reserved ***/
+
+ /* Remote console session ID */
+ memcpy(&(rsp->payload.open_session_response.console_id),
+ rsp->data + offset + 4,
+ 4);
+ #if WORDS_BIGENDIAN
+ rsp->payload.open_session_response.console_id =
+ BSWAP_32(rsp->payload.open_session_response.console_id);
+ #endif
+
+ /* only tag, status, privlvl, and console id are returned if error */
+ if (rsp->payload.open_session_response.rakp_return_code !=
+ IPMI_RAKP_STATUS_NO_ERRORS)
+ return;
+
+ /* BMC session ID */
+ memcpy(&(rsp->payload.open_session_response.bmc_id),
+ rsp->data + offset + 8,
+ 4);
+ #if WORDS_BIGENDIAN
+ rsp->payload.open_session_response.bmc_id =
+ BSWAP_32(rsp->payload.open_session_response.bmc_id);
+ #endif
+
+ /* And of course, our negotiated algorithms */
+ rsp->payload.open_session_response.auth_alg = rsp->data[offset + 16];
+ rsp->payload.open_session_response.integrity_alg = rsp->data[offset + 24];
+ rsp->payload.open_session_response.crypt_alg = rsp->data[offset + 32];
+}
+
+
+
+/*
+ * read_rakp2_message
+ *
+ * Initialize the ipmi_rs from the IPMI 2.x RAKP 2 message
+ *
+ * The offset should point the first byte of the the RAKP 2 payload when this
+ * function is called.
+ *
+ * param rsp [in/out] reading from the data variable and writing to the rakp 2
+ * section
+ * param offset [in] tells us where hte rakp2 payload starts
+ * param auth_alg [in] describes the authentication algorithm was agreed upon in
+ * the open session request/response phase. We need to know that here so
+ * that we know how many bytes (if any) to read fromt the packet.
+ *
+ * returns 0 on success, 1 on error
+ */
+void
+read_rakp2_message(
+ struct ipmi_rs * rsp,
+ int offset,
+ uint8_t auth_alg)
+{
+ int i;
+
+ /* Message tag */
+ rsp->payload.rakp2_message.message_tag = rsp->data[offset];
+
+ /* RAKP reponse code */
+ rsp->payload.rakp2_message.rakp_return_code = rsp->data[offset + 1];
+
+ /* Console session ID */
+ memcpy(&(rsp->payload.rakp2_message.console_id),
+ rsp->data + offset + 4,
+ 4);
+ #if WORDS_BIGENDIAN
+ rsp->payload.rakp2_message.console_id =
+ BSWAP_32(rsp->payload.rakp2_message.console_id);
+ #endif
+
+ /* BMC random number */
+ memcpy(&(rsp->payload.rakp2_message.bmc_rand),
+ rsp->data + offset + 8,
+ 16);
+ #if WORDS_BIGENDIAN
+ lanplus_swap(rsp->payload.rakp2_message.bmc_rand, 16);
+ #endif
+
+ /* BMC GUID */
+ memcpy(&(rsp->payload.rakp2_message.bmc_guid),
+ rsp->data + offset + 24,
+ 16);
+ #if WORDS_BIGENDIAN
+ lanplus_swap(rsp->payload.rakp2_message.bmc_guid, 16);
+ #endif
+
+ /* Key exchange authentication code */
+ switch (auth_alg)
+ {
+ case IPMI_AUTH_RAKP_NONE:
+ /* Nothing to do here */
+ break;
+
+ case IPMI_AUTH_RAKP_HMAC_SHA1:
+ /* We need to copy 20 bytes */
+ for (i = 0; i < SHA_DIGEST_LENGTH; ++i)
+ rsp->payload.rakp2_message.key_exchange_auth_code[i] =
+ rsp->data[offset + 40 + i];
+ break;
+
+ case IPMI_AUTH_RAKP_HMAC_MD5:
+ /* We need to copy 16 bytes */
+ for (i = 0; i < MD5_DIGEST_LENGTH; ++i)
+ rsp->payload.rakp2_message.key_exchange_auth_code[i] =
+ rsp->data[offset + 40 + i];
+ break;
+
+ case IPMI_AUTH_RAKP_HMAC_SHA256:
+ /* We need to copy 32 bytes */
+ for (i = 0; i < SHA256_DIGEST_LENGTH; ++i)
+ rsp->payload.rakp2_message.key_exchange_auth_code[i] =
+ rsp->data[offset + 40 + i];
+ break;
+
+ default:
+ lprintf(LOG_ERR, "read_rakp2_message: no support for authentication algorithm 0x%x", auth_alg);
+ assert(0); /*void routine*/
+ break;
+ }
+}
+
+
+
+/*
+ * read_rakp4_message
+ *
+ * Initialize the ipmi_rs from the IPMI 2.x RAKP 4 message
+ *
+ * The offset should point the first byte of the the RAKP 4 payload when this
+ * function is called.
+ *
+ * param rsp [in/out] reading from the data variable and writing to the rakp
+ * 4 section
+ * param offset [in] tells us where hte rakp4 payload starts
+ * param integrity_alg [in] describes the authentication algorithm was
+ * agreed upon in the open session request/response phase. We need
+ * to know that here so that we know how many bytes (if any) to read
+ * from the packet.
+ *
+ * returns 0 on success, 1 on error
+ */
+void
+read_rakp4_message(
+ struct ipmi_rs * rsp,
+ int offset,
+ uint8_t auth_alg)
+{
+ int i;
+
+ /* Message tag */
+ rsp->payload.rakp4_message.message_tag = rsp->data[offset];
+
+ /* RAKP reponse code */
+ rsp->payload.rakp4_message.rakp_return_code = rsp->data[offset + 1];
+
+ /* Console session ID */
+ memcpy(&(rsp->payload.rakp4_message.console_id),
+ rsp->data + offset + 4,
+ 4);
+ #if WORDS_BIGENDIAN
+ rsp->payload.rakp4_message.console_id =
+ BSWAP_32(rsp->payload.rakp4_message.console_id);
+ #endif
+
+
+ /* Integrity check value */
+ switch (auth_alg)
+ {
+ case IPMI_AUTH_RAKP_NONE:
+ /* Nothing to do here */
+ break;
+
+ case IPMI_AUTH_RAKP_HMAC_SHA1:
+ /* We need to copy 12 bytes */
+ for (i = 0; i < IPMI_SHA1_AUTHCODE_SIZE; ++i)
+ rsp->payload.rakp4_message.integrity_check_value[i] =
+ rsp->data[offset + 8 + i];
+ break;
+
+ case IPMI_AUTH_RAKP_HMAC_MD5:
+ /* We need to copy 16 bytes */
+ for (i = 0; i < IPMI_HMAC_MD5_AUTHCODE_SIZE; ++i)
+ rsp->payload.rakp4_message.integrity_check_value[i] =
+ rsp->data[offset + 8 + i];
+ break;
+
+ case IPMI_AUTH_RAKP_HMAC_SHA256:
+ /* We need to copy 16 bytes */
+ for (i = 0; i < IPMI_HMAC_SHA256_AUTHCODE_SIZE; ++i)
+ rsp->payload.rakp4_message.integrity_check_value[i] =
+ rsp->data[offset + 8 + i];
+ break;
+
+ default:
+ lprintf(LOG_ERR, "read_rakp4_message: no support "
+ "for authentication algorithm 0x%x", auth_alg);
+ assert(0); /*void routine*/
+ break;
+ }
+}
+
+
+
+
+/*
+ * read_session_data
+ *
+ * Initialize the ipmi_rsp from the session data in the packet
+ *
+ * The offset should point the first byte of the the IPMI session when this
+ * function is called.
+ *
+ * param rsp [in/out] we read from the data buffer and populate the session
+ * specific fields.
+ * param offset [in/out] should point to the beginning of the session when
+ * this function is called. The offset will be adjusted to
+ * point to the end of the session when this function exits.
+ * param session holds our session state
+ */
+int
+read_session_data(
+ struct ipmi_rs * rsp,
+ int * offset,
+ struct ipmi_session * s)
+{
+ int rv;
+ /* We expect to read different stuff depending on the authtype */
+ rsp->session.authtype = rsp->data[*offset];
+
+ if (rsp->session.authtype == IPMI_SESSION_AUTHTYPE_RMCP_PLUS)
+ rv = read_session_data_v2x(rsp, offset, s);
+ else
+ rv = read_session_data_v15(rsp, offset, s);
+ return(rv);
+}
+
+
+
+/*
+ * read_session_data_v2x
+ *
+ * Initialize the ipmi_rsp from the v2.x session header of the packet.
+ *
+ * The offset should point to the first byte of the the IPMI session when this
+ * function is called. When this function exits, offset will point to the
+ * start of payload.
+ *
+ * Should decrypt and perform integrity checking here?
+ *
+ * param rsp [in/out] we read from the data buffer and populate the session
+ * specific fields.
+ * param offset [in/out] should point to the beginning of the session when this
+ * function is called. The offset will be adjusted to point to
+ * the end of the session when this function exits.
+ * param s holds our session state
+ */
+int
+read_session_data_v2x(
+ struct ipmi_rs * rsp,
+ int * offset,
+ struct ipmi_session * s)
+{
+ rsp->session.authtype = rsp->data[(*offset)++];
+
+ rsp->session.bEncrypted = (rsp->data[*offset] & 0x80 ? 1 : 0);
+ rsp->session.bAuthenticated = (rsp->data[*offset] & 0x40 ? 1 : 0);
+
+
+ /* Payload type */
+ rsp->session.payloadtype = rsp->data[(*offset)++] & 0x3F;
+
+ /* Session ID */
+ memcpy(&rsp->session.id, rsp->data + *offset, 4);
+ *offset += 4;
+ #if WORDS_BIGENDIAN
+ rsp->session.id = BSWAP_32(rsp->session.id);
+ #endif
+
+
+ /*
+ * Verify that the session ID is what we think it should be
+ */
+ if ((s->v2_data.session_state == LANPLUS_STATE_ACTIVE) &&
+ (rsp->session.id != s->v2_data.console_id))
+ {
+ lprintf(LOG_ERR, "packet session id 0x%x does not "
+ "match active session 0x%0x",
+ rsp->session.id, s->v2_data.console_id);
+ /* assert(0); * the session is broken, cannot proceed */
+ /* return and abort session here. */
+ return(-13); /* LAN_ERR_OTHER = -13 */
+ }
+
+
+ /* Ignored, so far */
+ memcpy(&rsp->session.seq, rsp->data + *offset, 4);
+ *offset += 4;
+ #if WORDS_BIGENDIAN
+ rsp->session.seq = BSWAP_32(rsp->session.seq);
+ #endif
+
+ memcpy(&rsp->session.msglen, rsp->data + *offset, 2);
+ *offset += 2;
+ #if WORDS_BIGENDIAN
+ rsp->session.msglen = BSWAP_16(rsp->session.msglen);
+ #endif
+ return(0);
+}
+
+
+
+/*
+ * read_session_data_v15
+ *
+ * Initialize the ipmi_rsp from the session header of the packet.
+ *
+ * The offset should point the first byte of the the IPMI session when this
+ * function is called. When this function exits, the offset will point to
+ * the start of the IPMI message.
+ *
+ * param rsp [in/out] we read from the data buffer and populate the session
+ * specific fields.
+ * param offset [in/out] should point to the beginning of the session when this
+ * function is called. The offset will be adjusted to point to the
+ * end of the session when this function exits.
+ * param s holds our session state
+ */
+int read_session_data_v15(
+ struct ipmi_rs * rsp,
+ int * offset,
+ struct ipmi_session * s)
+{
+ /* All v15 messages are IPMI messages */
+ rsp->session.payloadtype = IPMI_PAYLOAD_TYPE_IPMI;
+
+ rsp->session.authtype = rsp->data[(*offset)++];
+
+ /* All v15 messages that we will receive are unencrypted/unauthenticated */
+ rsp->session.bEncrypted = 0;
+ rsp->session.bAuthenticated = 0;
+
+ /* skip the session id and sequence number fields */
+ *offset += 8;
+
+ /* This is the size of the whole payload */
+ rsp->session.msglen = rsp->data[(*offset)++];
+ return(0);
+}
+
+
+
+/*
+ * read_ipmi_response
+ *
+ * Initialize the impi_rs from with the IPMI response specific data
+ *
+ * The offset should point the first byte of the the IPMI payload when this
+ * function is called.
+ *
+ * param rsp [in/out] we read from the data buffer and populate the IPMI
+ * specific fields.
+ * param offset [in/out] should point to the beginning of the IPMI payload when
+ * this function is called.
+ */
+void read_ipmi_response(struct ipmi_rs * rsp, int * offset)
+{
+ /*
+ * The data here should be decrypted by now.
+ */
+ rsp->payload.ipmi_response.rq_addr = rsp->data[(*offset)++];
+ rsp->payload.ipmi_response.netfn = rsp->data[*offset] >> 2;
+ rsp->payload.ipmi_response.rq_lun = rsp->data[(*offset)++] & 0x3;
+ (*offset)++; /* checksum */
+ rsp->payload.ipmi_response.rs_addr = rsp->data[(*offset)++];
+ rsp->payload.ipmi_response.rq_seq = rsp->data[*offset] >> 2;
+ rsp->payload.ipmi_response.rs_lun = rsp->data[(*offset)++] & 0x3;
+ rsp->payload.ipmi_response.cmd = rsp->data[(*offset)++];
+ rsp->ccode = rsp->data[(*offset)++];
+
+}
+
+
+
+/*
+ * read_sol_packet
+ *
+ * Initialize the ipmi_rs with the SOL response data
+ *
+ * The offset should point the first byte of the the SOL payload when this
+ * function is called.
+ *
+ * param rsp [in/out] we read from the data buffer and populate the
+ * SOL specific fields.
+ * param offset [in/out] should point to the beginning of the SOL payload
+ * when this function is called.
+ */
+void read_sol_packet(struct ipmi_rs * rsp, int * offset)
+{
+
+ /*
+ * The data here should be decrypted by now.
+ */
+ rsp->payload.sol_packet.packet_sequence_number =
+ rsp->data[(*offset)++] & 0x0F;
+
+ rsp->payload.sol_packet.acked_packet_number =
+ rsp->data[(*offset)++] & 0x0F;
+
+ rsp->payload.sol_packet.accepted_character_count =
+ rsp->data[(*offset)++];
+
+ rsp->payload.sol_packet.is_nack =
+ rsp->data[*offset] & 0x40;
+
+ rsp->payload.sol_packet.transfer_unavailable =
+ rsp->data[*offset] & 0x20;
+
+ rsp->payload.sol_packet.sol_inactive =
+ rsp->data[*offset] & 0x10;
+
+ rsp->payload.sol_packet.transmit_overrun =
+ rsp->data[*offset] & 0x08;
+
+ rsp->payload.sol_packet.break_detected =
+ rsp->data[(*offset)++] & 0x04;
+
+ lprintf(LOG_DEBUG, "<<<<<<<<<< RECV FROM BMC <<<<<<<<<<<");
+ lprintf(LOG_DEBUG, "< SOL sequence number : 0x%02x",
+ rsp->payload.sol_packet.packet_sequence_number);
+ lprintf(LOG_DEBUG, "< SOL acked packet : 0x%02x",
+ rsp->payload.sol_packet.acked_packet_number);
+ lprintf(LOG_DEBUG, "< SOL accepted char count : 0x%02x",
+ rsp->payload.sol_packet.accepted_character_count);
+ lprintf(LOG_DEBUG, "< SOL is nack : %s",
+ rsp->payload.sol_packet.is_nack? "true" : "false");
+ lprintf(LOG_DEBUG, "< SOL xfer unavailable : %s",
+ rsp->payload.sol_packet.transfer_unavailable? "true" : "false");
+ lprintf(LOG_DEBUG, "< SOL inactive : %s",
+ rsp->payload.sol_packet.sol_inactive? "true" : "false");
+ lprintf(LOG_DEBUG, "< SOL transmit overrun : %s",
+ rsp->payload.sol_packet.transmit_overrun? "true" : "false");
+ lprintf(LOG_DEBUG, "< SOL break detected : %s",
+ rsp->payload.sol_packet.break_detected? "true" : "false");
+ lprintf(LOG_DEBUG, "< rs Session sequence num : %d",
+ rsp->session.seq);
+ lprintf(LOG_DEBUG, "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");
+
+ if (verbose >= 5)
+ printbuf(rsp->data + *offset - 4, 4, "SOL MSG FROM BMC");
+}
+
+
+
+/*
+ * getIpmiPayloadWireRep
+ *
+ * param out [out] will contain our wire representation
+ * param req [in] is the IPMI request to be written
+ * param crypt_alg [in] specifies the encryption to use
+ * param rq_seq [in] is the IPMI command sequence number.
+ */
+void getIpmiPayloadWireRep(
+ struct ipmi_intf * intf, /* in out */
+ struct ipmi_v2_payload * payload, /* in */
+ uint8_t * msg,
+ struct ipmi_rq * req,
+ uint8_t rq_seq,
+ uint8_t curr_seq)
+{
+ int cs, tmp, len;
+ int cs2 = 0;
+ int cs3 = 0;
+ uint8_t ourAddress = (uint8_t)intf->my_addr;
+ uint8_t bridgedRequest = 0;
+
+ if (ourAddress == 0)
+ ourAddress = IPMI_BMC_SLAVE_ADDR;
+
+ len = 0;
+
+ /* IPMI Message Header -- Figure 13-4 of the IPMI v2.0 spec */
+ if ((intf->target_addr == ourAddress) || (!bridgePossible))
+ cs = len;
+ else {
+ bridgedRequest = 1;
+ if(intf->transit_addr != ourAddress && intf->transit_addr != 0)
+ {
+ bridgedRequest++;
+ }
+ /* bridged request: encapsulate w/in Send Message */
+ cs = len;
+ msg[len++] = IPMI_BMC_SLAVE_ADDR;
+ msg[len++] = IPMI_NETFN_APP << 2;
+ tmp = len - cs;
+ msg[len++] = ipmi_csum(msg+cs, tmp);
+ cs2 = len;
+ msg[len++] = IPMI_REMOTE_SWID;
+ msg[len++] = curr_seq << 2;
+ msg[len++] = 0x34; /* Send Message rqst */
+ if(bridgedRequest == 2)
+ msg[len++] = (0x40|intf->transit_channel); /* Track request*/
+ else
+ msg[len++] = (0x40|intf->target_channel); /* Track request*/
+#if 0 /* From lan.c example */
+ entry->req.msg.target_cmd = entry->req.msg.cmd; /* Save target command */
+ entry->req.msg.cmd = 0x34; /* (fixup request entry) */
+#endif
+ payload->payload_length += 7;
+ cs = len;
+ if(bridgedRequest == 2)
+ {
+ /* bridged request: encapsulate w/in Send Message */
+ cs = len;
+ msg[len++] = (uint8_t)intf->transit_addr;
+ msg[len++] = IPMI_NETFN_APP << 2;
+ tmp = len - cs;
+ msg[len++] = ipmi_csum(msg+cs, tmp);
+ cs3 = len;
+ msg[len++] = (uint8_t)intf->my_addr;
+ msg[len++] = curr_seq << 2;
+ msg[len++] = 0x34; /* Send Message rqst */
+ msg[len++] = (0x40|intf->target_channel); /* Track request*/
+ payload->payload_length += 7;
+ cs = len;
+ }
+ }
+
+ /* rsAddr */
+ msg[len++] = (uint8_t)intf->target_addr; /* IPMI_BMC_SLAVE_ADDR; */
+
+ /* net Fn */
+ msg[len++] = req->msg.netfn << 2 | (req->msg.lun & 3);
+ tmp = len - cs;
+
+ /* checkSum */
+ msg[len++] = ipmi_csum(msg+cs, tmp);
+ cs = len;
+
+ /* rqAddr */
+ if (!bridgedRequest)
+ msg[len++] = IPMI_REMOTE_SWID;
+ else /* Bridged message */
+ msg[len++] = (uint8_t)intf->my_addr;
+
+ /* rqSeq / rqLUN */
+ msg[len++] = rq_seq << 2;
+
+ /* cmd */
+ msg[len++] = req->msg.cmd;
+
+ /* message data */
+ if (req->msg.data_len) {
+ memcpy(msg + len, req->msg.data, req->msg.data_len);
+ len += req->msg.data_len;
+ }
+
+ /* second checksum */
+ tmp = len - cs;
+ msg[len++] = ipmi_csum(msg+cs, tmp);
+
+ /* Dual bridged request: 2nd checksum */
+ if (bridgedRequest == 2) {
+ tmp = len - cs3;
+ msg[len++] = ipmi_csum(msg+cs3, tmp);
+ payload->payload_length += 1;
+ }
+
+ /* bridged request: 2nd checksum */
+ if (bridgedRequest) {
+ tmp = len - cs2;
+ msg[len++] = ipmi_csum(msg+cs2, tmp);
+ payload->payload_length += 1;
+ if (verbose)
+ printbuf(msg,len,"Bridged Request");
+ }
+}
+
+
+
+/*
+ * getSolPayloadWireRep
+ *
+ * param msg [out] will contain our wire representation
+ * param payload [in] holds the v2 payload with our SOL data
+ */
+void getSolPayloadWireRep(
+ struct ipmi_intf * intf, /* in out */
+ uint8_t * msg, /* output */
+ struct ipmi_v2_payload * payload) /* input */
+{
+ int i = 0;
+
+ lprintf(LOG_DEBUG, ">>>>>>>>>> SENDING TO BMC >>>>>>>>>>");
+ lprintf(LOG_DEBUG, "> SOL sequence number : 0x%02x",
+ payload->payload.sol_packet.packet_sequence_number);
+ lprintf(LOG_DEBUG, "> SOL acked packet : 0x%02x",
+ payload->payload.sol_packet.acked_packet_number);
+ lprintf(LOG_DEBUG, "> SOL accepted char count : 0x%02x",
+ payload->payload.sol_packet.accepted_character_count);
+ lprintf(LOG_DEBUG, "> SOL is nack : %s",
+ payload->payload.sol_packet.is_nack ? "true" : "false");
+ lprintf(LOG_DEBUG, "> SOL assert ring wor : %s",
+ payload->payload.sol_packet.assert_ring_wor ? "true" : "false");
+ lprintf(LOG_DEBUG, "> SOL generate break : %s",
+ payload->payload.sol_packet.generate_break ? "true" : "false");
+ lprintf(LOG_DEBUG, "> SOL deassert cts : %s",
+ payload->payload.sol_packet.deassert_cts ? "true" : "false");
+ lprintf(LOG_DEBUG, "> SOL deassert dcd dsr : %s",
+ payload->payload.sol_packet.deassert_dcd_dsr ? "true" : "false");
+ lprintf(LOG_DEBUG, "> SOL flush inbound : %s",
+ payload->payload.sol_packet.flush_inbound ? "true" : "false");
+ lprintf(LOG_DEBUG, "> SOL flush outbound : %s",
+ payload->payload.sol_packet.flush_outbound ? "true" : "false");
+
+ msg[i++] = payload->payload.sol_packet.packet_sequence_number;
+ msg[i++] = payload->payload.sol_packet.acked_packet_number;
+ msg[i++] = payload->payload.sol_packet.accepted_character_count;
+
+ msg[i] = payload->payload.sol_packet.is_nack ? 0x40 : 0;
+ msg[i] |= payload->payload.sol_packet.assert_ring_wor ? 0x20 : 0;
+ msg[i] |= payload->payload.sol_packet.generate_break ? 0x10 : 0;
+ msg[i] |= payload->payload.sol_packet.deassert_cts ? 0x08 : 0;
+ msg[i] |= payload->payload.sol_packet.deassert_dcd_dsr ? 0x04 : 0;
+ msg[i] |= payload->payload.sol_packet.flush_inbound ? 0x02 : 0;
+ msg[i++] |= payload->payload.sol_packet.flush_outbound ? 0x01 : 0;
+
+ /* We may have data to add */
+ memcpy(msg + i,
+ payload->payload.sol_packet.data,
+ payload->payload.sol_packet.character_count);
+
+ lprintf(LOG_DEBUG, "> SOL character count : %d",
+ payload->payload.sol_packet.character_count);
+ lprintf(LOG_DEBUG, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
+
+ if (verbose >= 5 && payload->payload.sol_packet.character_count)
+ printbuf(payload->payload.sol_packet.data, payload->payload.sol_packet.character_count, "SOL SEND DATA");
+
+ /*
+ * At this point, the payload length becomes the whole payload
+ * length, including the 4 bytes at the beginning of the SOL
+ * packet
+ */
+ payload->payload_length = payload->payload.sol_packet.character_count + 4;
+}
+
+
+
+/*
+ * ipmi_lanplus_build_v2x_msg
+ *
+ * Encapsulates the payload data to create the IPMI v2.0 / RMCP+ packet.
+ *
+ *
+ * IPMI v2.0 LAN Request Message Format
+ * +----------------------+
+ * | rmcp.ver | 4 bytes
+ * | rmcp.__rsvd |
+ * | rmcp.seq |
+ * | rmcp.class |
+ * +----------------------+
+ * | session.authtype | 10 bytes
+ * | session.payloadtype |
+ * | session.id |
+ * | session.seq |
+ * +----------------------+
+ * | message length | 2 bytes
+ * +----------------------+
+ * | Confidentiality Hdr | var (possibly absent)
+ * +----------------------+
+ * | Payload | var Payload
+ * +----------------------+
+ * | Confidentiality Trlr | var (possibly absent)
+ * +----------------------+
+ * | Integrity pad | var (possibly absent)
+ * +----------------------+
+ * | Pad length | 1 byte (WTF?)
+ * +----------------------+
+ * | Next Header | 1 byte (WTF?)
+ * +----------------------+
+ * | Authcode | var (possibly absent)
+ * +----------------------+
+ */
+int
+ipmi_lanplus_build_v2x_msg(
+ struct ipmi_intf * intf, /* in */
+ struct ipmi_v2_payload * payload, /* in */
+ int * msg_len, /* out */
+ uint8_t ** msg_data, /* out */
+ uint8_t curr_seq)
+{
+ uint32_t session_trailer_length = 0;
+ struct ipmi_session * session = intf->session;
+ /* msg will hold the entire message to be sent */
+ uint8_t * msg;
+ int len = 0;
+ int rv = 0;
+#if defined(WIN32) || defined(SOLARIS)
+ struct rmcp_hdr rmcp;
+
+ rmcp.ver = RMCP_VERSION_1;
+ rmcp.class = RMCP_CLASS_IPMI;
+ rmcp.seq = 0xff;
+ rmcp.__rsvd = 0;
+#else
+ struct rmcp_hdr rmcp = {
+ .ver = RMCP_VERSION_1,
+ .__rsvd = 0,
+ .class = RMCP_CLASS_IPMI,
+ .seq = 0xff,
+ };
+#endif
+
+ len =
+ sizeof(rmcp) + // RMCP Header (4)
+ 10 + // IPMI Session Header
+ 2 + // Message length
+ payload->payload_length + // The actual payload
+ IPMI_MAX_INTEGRITY_PAD_SIZE + // Integrity Pad
+ 1 + // Pad Length
+ 1 + // Next Header
+ IPMI_MAX_AUTH_CODE_SIZE; // Authcode (usu 20+16)
+
+ msg = malloc(len);
+ if (msg == NULL) {
+ lprintf(LOG_ERR, "lanplus: malloc failure");
+ return -1;
+ }
+ memset(msg, 0, len);
+
+ /*
+ *------------------------------------------
+ * RMCP HEADER
+ *------------------------------------------
+ */
+ memcpy(msg, &rmcp, sizeof(rmcp));
+ len = sizeof(rmcp);
+
+
+ /*
+ *------------------------------------------
+ * IPMI SESSION HEADER
+ *------------------------------------------
+ */
+ /* ipmi session Auth Type / Format is always 0x06 for IPMI v2 */
+ msg[IPMI_LANPLUS_OFFSET_AUTHTYPE] = 0x06;
+
+ /* Payload Type -- also specifies whether were authenticated/encyrpted */
+ msg[IPMI_LANPLUS_OFFSET_PAYLOAD_TYPE] = payload->payload_type;
+
+ if (session->v2_data.session_state == LANPLUS_STATE_ACTIVE)
+ {
+ msg[IPMI_LANPLUS_OFFSET_PAYLOAD_TYPE] |=
+ ((session->v2_data.crypt_alg != IPMI_CRYPT_NONE )? 0x80 : 0x00);
+ msg[IPMI_LANPLUS_OFFSET_PAYLOAD_TYPE] |=
+ ((session->v2_data.integrity_alg != IPMI_INTEGRITY_NONE)? 0x40 : 0x00);
+ }
+
+ if (session->v2_data.session_state == LANPLUS_STATE_ACTIVE)
+ {
+ /* Session ID -- making it LSB */
+ msg[IPMI_LANPLUS_OFFSET_SESSION_ID ] = session->v2_data.bmc_id & 0xff;
+ msg[IPMI_LANPLUS_OFFSET_SESSION_ID + 1] = (session->v2_data.bmc_id >> 8) & 0xff;
+ msg[IPMI_LANPLUS_OFFSET_SESSION_ID + 2] = (session->v2_data.bmc_id >> 16) & 0xff;
+ msg[IPMI_LANPLUS_OFFSET_SESSION_ID + 3] = (session->v2_data.bmc_id >> 24) & 0xff;
+
+ /* Sequence Number -- making it LSB */
+ msg[IPMI_LANPLUS_OFFSET_SEQUENCE_NUM ] = session->out_seq & 0xff;
+ msg[IPMI_LANPLUS_OFFSET_SEQUENCE_NUM + 1] = (session->out_seq >> 8) & 0xff;
+ msg[IPMI_LANPLUS_OFFSET_SEQUENCE_NUM + 2] = (session->out_seq >> 16) & 0xff;
+ msg[IPMI_LANPLUS_OFFSET_SEQUENCE_NUM + 3] = (session->out_seq >> 24) & 0xff;
+ }
+
+ /*
+ * Payload Length is set below (we don't know how big the payload is until after
+ * encryption).
+ */
+
+ /*
+ * Payload
+ *
+ * At this point we are ready to slam the payload in.
+ * This includes:
+ * 1) The confidentiality header
+ * 2) The payload proper (possibly encrypted)
+ * 3) The confidentiality trailer
+ *
+ */
+ switch (payload->payload_type)
+ {
+ case IPMI_PAYLOAD_TYPE_IPMI:
+ getIpmiPayloadWireRep(intf,
+ payload, /* in */
+ msg + IPMI_LANPLUS_OFFSET_PAYLOAD,
+ payload->payload.ipmi_request.request,
+ payload->payload.ipmi_request.rq_seq,
+ curr_seq);
+ break;
+
+ case IPMI_PAYLOAD_TYPE_SOL:
+ getSolPayloadWireRep(intf,
+ msg + IPMI_LANPLUS_OFFSET_PAYLOAD,
+ payload);
+
+ if (verbose >= 5)
+ printbuf(msg + IPMI_LANPLUS_OFFSET_PAYLOAD, 4, "SOL MSG TO BMC");
+
+ len += payload->payload_length;
+
+ break;
+
+ case IPMI_PAYLOAD_TYPE_RMCP_OPEN_REQUEST:
+ /* never encrypted, so our job is easy */
+ memcpy(msg + IPMI_LANPLUS_OFFSET_PAYLOAD,
+ payload->payload.open_session_request.request,
+ payload->payload_length);
+ len += payload->payload_length;
+ break;
+
+ case IPMI_PAYLOAD_TYPE_RAKP_1:
+ /* never encrypted, so our job is easy */
+ memcpy(msg + IPMI_LANPLUS_OFFSET_PAYLOAD,
+ payload->payload.rakp_1_message.message,
+ payload->payload_length);
+ len += payload->payload_length;
+ break;
+
+ case IPMI_PAYLOAD_TYPE_RAKP_3:
+ /* never encrypted, so our job is easy */
+ memcpy(msg + IPMI_LANPLUS_OFFSET_PAYLOAD,
+ payload->payload.rakp_3_message.message,
+ payload->payload_length);
+ len += payload->payload_length;
+ break;
+
+ default:
+ lprintf(LOG_ERR, "unsupported payload type 0x%x",
+ payload->payload_type);
+ free(msg);
+ return -1;
+ break;
+ }
+
+
+ /*
+ *------------------------------------------
+ * ENCRYPT THE PAYLOAD IF NECESSARY
+ *------------------------------------------
+ */
+ if (session->v2_data.session_state == LANPLUS_STATE_ACTIVE)
+ {
+ /* Payload len is adjusted as necessary by lanplus_encrypt_payload */
+ lanplus_encrypt_payload(session->v2_data.crypt_alg, /* input */
+ session->v2_data.k2, /* input */
+ msg + IPMI_LANPLUS_OFFSET_PAYLOAD, /* input */
+ payload->payload_length, /* input */
+ msg + IPMI_LANPLUS_OFFSET_PAYLOAD, /* output */
+ &(payload->payload_length)); /* output */
+
+ }
+
+ /* Now we know the payload length */
+ msg[IPMI_LANPLUS_OFFSET_PAYLOAD_SIZE ] =
+ payload->payload_length & 0xff;
+ msg[IPMI_LANPLUS_OFFSET_PAYLOAD_SIZE + 1] =
+ (payload->payload_length >> 8) & 0xff;
+
+
+ /*
+ *------------------------------------------
+ * SESSION TRAILER
+ *------------------------------------------
+ */
+ if ((session->v2_data.session_state == LANPLUS_STATE_ACTIVE) &&
+ (session->v2_data.integrity_alg != IPMI_INTEGRITY_NONE))
+ {
+ uint32_t hmac_length, hmac_input_size;
+ uint32_t i, auth_length = 0, integrity_pad_size = 0;
+ uint8_t * hmac_output;
+ uint32_t start_of_session_trailer =
+ IPMI_LANPLUS_OFFSET_PAYLOAD +
+ payload->payload_length;
+
+
+ /*
+ * Determine the required integrity pad length. We have to make the
+ * data range covered by the authcode a multiple of 4.
+ */
+ uint32_t length_before_authcode;
+
+ if (ipmi_oem_active(intf, "icts")) {
+ length_before_authcode =
+ 12 + /* the stuff before the payload */
+ payload->payload_length;
+ } else {
+ length_before_authcode =
+ 12 + /* the stuff before the payload */
+ payload->payload_length +
+ 1 + /* pad length field */
+ 1; /* next header field */
+ }
+
+ if (length_before_authcode % 4)
+ integrity_pad_size = 4 - (length_before_authcode % 4);
+
+ for (i = 0; i < integrity_pad_size; ++i)
+ msg[start_of_session_trailer + i] = 0xFF;
+
+ /* Pad length */
+ msg[start_of_session_trailer + integrity_pad_size] = (uint8_t)integrity_pad_size;
+
+ /* Next Header */
+ msg[start_of_session_trailer + integrity_pad_size + 1] =
+ 0x07; /* Hardcoded per the spec, table 13-8 */
+
+ hmac_input_size =
+ 12 +
+ payload->payload_length +
+ integrity_pad_size +
+ 2;
+
+ hmac_output =
+ msg +
+ IPMI_LANPLUS_OFFSET_PAYLOAD +
+ payload->payload_length +
+ integrity_pad_size +
+ 2;
+
+ if (verbose > 2)
+ printbuf(msg + IPMI_LANPLUS_OFFSET_AUTHTYPE, hmac_input_size, "authcode input");
+
+ /* Auth Code */
+ hmac_length = 20; /* init length, just in case*/
+ lanplus_HMAC(session->v2_data.integrity_alg,
+ session->v2_data.k1, /*key */
+ session->v2_data.k1_len, /*key length*/
+ msg + IPMI_LANPLUS_OFFSET_AUTHTYPE, /*hmac input*/
+ hmac_input_size,
+ hmac_output,
+ &hmac_length);
+
+ switch(session->v2_data.integrity_alg)
+ {
+ case IPMI_INTEGRITY_HMAC_SHA1_96:
+ if (hmac_length != SHA_DIGEST_LENGTH) rv = -1;
+ auth_length = IPMI_SHA1_AUTHCODE_SIZE;
+ break;
+ case IPMI_INTEGRITY_HMAC_MD5_128 :
+ if (hmac_length != MD5_DIGEST_LENGTH) rv = -1;
+ auth_length = IPMI_HMAC_MD5_AUTHCODE_SIZE;
+ break;
+#ifdef HAVE_SHA256
+ /* based on an MD5_SHA256 patch from Holger Liebig */
+ case IPMI_INTEGRITY_HMAC_SHA256_128:
+ if (hmac_length != SHA256_DIGEST_LENGTH) rv = -1;
+ auth_length = IPMI_HMAC_SHA256_AUTHCODE_SIZE;
+ break;
+#endif
+ default:
+ lprintf(LOG_ERR,"unsupported integrity_alg 0x%x",
+ session->v2_data.integrity_alg);
+ free(msg);
+ return -1; //assert(0);
+ break;
+ }
+ if (rv != 0) {
+ lprintf(LOG_ERR,"Invalid alg %d length %d",
+ session->v2_data.integrity_alg, hmac_length);
+ return(rv);
+ }
+
+ if (verbose > 2)
+ printbuf(hmac_output, auth_length, "authcode output");
+
+ /* Set session_trailer_length appropriately */
+ session_trailer_length =
+ integrity_pad_size +
+ 2 + /* pad length + next header */
+ auth_length; /* Size of the authcode (we only use the first 12 bytes) */
+ }
+
+
+ ++(session->out_seq);
+ if (!session->out_seq)
+ ++(session->out_seq);
+
+ *msg_len =
+ IPMI_LANPLUS_OFFSET_PAYLOAD +
+ payload->payload_length +
+ session_trailer_length;
+ *msg_data = msg;
+ return 0;
+}
+
+
+
+/*
+ * ipmi_lanplus_build_v2x_ipmi_cmd
+ *
+ * Wraps ipmi_lanplus_build_v2x_msg and returns a new entry object for the
+ * command
+ *
+ */
+static struct ipmi_rq_entry *
+ipmi_lanplus_build_v2x_ipmi_cmd(
+ struct ipmi_intf * intf,
+ struct ipmi_rq * req)
+{
+ struct ipmi_v2_payload v2_payload;
+ struct ipmi_rq_entry * entry;
+ int rv;
+
+ /*
+ * We have a problem. we need to know the sequence number here,
+ * because we use it in our stored entry. But we also need to
+ * know the sequence number when we generate our IPMI
+ * representation far below.
+ */
+ static uint8_t curr_seq = 0;
+
+ curr_seq += 1;
+
+ if (curr_seq >= 64)
+ curr_seq = 0;
+
+ /* IPMI Message Header -- Figure 13-4 of the IPMI v2.0 spec */
+ if ((intf->target_addr == intf->my_addr) || (!bridgePossible))
+ {
+ entry = ipmi_req_add_entry(intf, req, curr_seq);
+ }
+ else /* it's a bridge command */
+ {
+ unsigned char backup_cmd;
+
+ /* Add entry for cmd */
+ entry = ipmi_req_add_entry(intf, req, curr_seq);
+
+ if (entry)
+ {
+ /* Add entry for bridge cmd */
+ backup_cmd = req->msg.cmd;
+ req->msg.cmd = 0x34;
+ entry = ipmi_req_add_entry(intf, req, curr_seq);
+ req->msg.cmd = backup_cmd;
+ }
+ }
+
+ if (entry == NULL)
+ return NULL;
+
+ // Build our payload
+ v2_payload.payload_type = IPMI_PAYLOAD_TYPE_IPMI;
+ v2_payload.payload_length = req->msg.data_len + 7;
+ v2_payload.payload.ipmi_request.request = req;
+ v2_payload.payload.ipmi_request.rq_seq = curr_seq;
+
+ rv = ipmi_lanplus_build_v2x_msg(intf, // in
+ &v2_payload, // in
+ &(entry->msg_len), // out
+ &(entry->msg_data), // out
+ curr_seq); // in
+ if (rv != 0) return NULL;
+
+ return entry;
+}
+
+
+
+
+
+/*
+ * IPMI LAN Request Message Format
+ * +--------------------+
+ * | rmcp.ver | 4 bytes
+ * | rmcp.__rsvd |
+ * | rmcp.seq |
+ * | rmcp.class |
+ * +--------------------+
+ * | session.authtype | 9 bytes
+ * | session.seq |
+ * | session.id |
+ * +--------------------+
+ * | [session.authcode] | 16 bytes (AUTHTYPE != none)
+ * +--------------------+
+ * | message length | 1 byte
+ * +--------------------+
+ * | message.rs_addr | 6 bytes
+ * | message.netfn_lun |
+ * | message.checksum |
+ * | message.rq_addr |
+ * | message.rq_seq |
+ * | message.cmd |
+ * +--------------------+
+ * | [request data] | data_len bytes
+ * +--------------------+
+ * | checksum | 1 byte
+ * +--------------------+
+ */
+static struct ipmi_rq_entry *
+ipmi_lanplus_build_v15_ipmi_cmd(
+ struct ipmi_intf * intf,
+ struct ipmi_rq * req)
+{
+ uint8_t * msg;
+ int cs, mp, len = 0, tmp;
+ struct ipmi_session * session = intf->session;
+ struct ipmi_rq_entry * entry;
+#if defined(WIN32) || defined(SOLARIS)
+ struct rmcp_hdr rmcp;
+
+ rmcp.ver = RMCP_VERSION_1;
+ rmcp.class = RMCP_CLASS_IPMI;
+ rmcp.seq = 0xff;
+ rmcp.__rsvd = 0;
+#else
+ struct rmcp_hdr rmcp = {
+ .ver = RMCP_VERSION_1,
+ .__rsvd = 0,
+ .class = RMCP_CLASS_IPMI,
+ .seq = 0xff,
+ };
+#endif
+
+ entry = ipmi_req_add_entry(intf, req, 0);
+ if (entry == NULL)
+ return NULL;
+
+ len = req->msg.data_len + 21;
+
+ msg = malloc(len);
+ if (msg == NULL) {
+ lprintf(LOG_ERR, "lanplus: malloc failure");
+ free(entry);
+ return NULL;
+ }
+ memset(msg, 0, len);
+
+ /* rmcp header */
+ memcpy(msg, &rmcp, sizeof(rmcp));
+ len = sizeof(rmcp);
+
+ /*
+ * ipmi session header
+ */
+ /* Authtype should always be none for 1.5 packets sent from this
+ * interface
+ */
+ msg[len++] = IPMI_SESSION_AUTHTYPE_NONE;
+
+ msg[len++] = session->out_seq & 0xff;
+ msg[len++] = (session->out_seq >> 8) & 0xff;
+ msg[len++] = (session->out_seq >> 16) & 0xff;
+ msg[len++] = (session->out_seq >> 24) & 0xff;
+
+ /*
+ * The session ID should be all zeroes for pre-session commands. We
+ * should only be using the 1.5 interface for the pre-session Get
+ * Channel Authentication Capabilities command
+ */
+ msg[len++] = 0;
+ msg[len++] = 0;
+ msg[len++] = 0;
+ msg[len++] = 0;
+
+ /* message length */
+ msg[len++] = req->msg.data_len + 7;
+
+ /* ipmi message header */
+ cs = mp = len;
+ msg[len++] = IPMI_BMC_SLAVE_ADDR;
+ msg[len++] = req->msg.netfn << 2;
+ tmp = len - cs;
+ msg[len++] = ipmi_csum(msg+cs, tmp);
+ cs = len;
+ msg[len++] = IPMI_REMOTE_SWID;
+
+ entry->rq_seq = 0; /*should swseq start w 1?*/
+
+ msg[len++] = entry->rq_seq << 2;
+ msg[len++] = req->msg.cmd;
+
+ lprintf(LOG_DEBUG+1, ">> IPMI Request Session Header");
+ lprintf(LOG_DEBUG+1, ">> Authtype : %s",
+ val2str(IPMI_SESSION_AUTHTYPE_NONE, ipmi_authtype_session_vals));
+ lprintf(LOG_DEBUG+1, ">> Sequence : 0x%08lx",
+ (long)session->out_seq);
+ lprintf(LOG_DEBUG+1, ">> Session ID : 0x%08lx",
+ (long)0);
+
+ lprintf(LOG_DEBUG+1, ">> IPMI Request Message Header");
+ lprintf(LOG_DEBUG+1, ">> Rs Addr : %02x", IPMI_BMC_SLAVE_ADDR);
+ lprintf(LOG_DEBUG+1, ">> NetFn : %02x", req->msg.netfn);
+ lprintf(LOG_DEBUG+1, ">> Rs LUN : %01x", 0);
+ lprintf(LOG_DEBUG+1, ">> Rq Addr : %02x", IPMI_REMOTE_SWID);
+ lprintf(LOG_DEBUG+1, ">> Rq Seq : %02x", entry->rq_seq);
+ lprintf(LOG_DEBUG+1, ">> Rq Lun : %01x", 0);
+ lprintf(LOG_DEBUG+1, ">> Command : %02x", req->msg.cmd);
+
+ /* message data */
+ if (req->msg.data_len) {
+ memcpy(msg+len, req->msg.data, req->msg.data_len);
+ len += req->msg.data_len;
+ }
+
+ /* second checksum */
+ tmp = len - cs;
+ msg[len++] = ipmi_csum(msg+cs, tmp);
+
+ entry->msg_len = len;
+ entry->msg_data = msg;
+
+ return entry;
+}
+
+
+
+/*
+ * is_sol_packet
+ */
+static int
+is_sol_packet(struct ipmi_rs * rsp)
+{
+ return (rsp &&
+ (rsp->session.authtype == IPMI_SESSION_AUTHTYPE_RMCP_PLUS) &&
+ (rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_SOL));
+}
+
+
+
+/*
+ * sol_response_acks_packet
+ */
+static int
+sol_response_acks_packet(
+ struct ipmi_rs * rsp,
+ struct ipmi_v2_payload * payload)
+{
+ return (is_sol_packet(rsp) &&
+ payload &&
+ (payload->payload_type == IPMI_PAYLOAD_TYPE_SOL) &&
+ (rsp->payload.sol_packet.acked_packet_number ==
+ payload->payload.sol_packet.packet_sequence_number));
+}
+
+
+
+/*
+ * ipmi_lanplus_send_payload
+ *
+ */
+struct ipmi_rs *
+ipmi_lanplus_send_payload(
+ struct ipmi_intf * intf,
+ struct ipmi_v2_payload * payload)
+{
+ struct ipmi_rs * rsp = NULL;
+ uint8_t * msg_data = NULL;
+ int msg_length;
+ struct ipmi_session * session = intf->session;
+ int itry = 0;
+ int xmit = 1;
+ time_t ltime;
+ int rv = 0;
+ struct ipmi_rq_entry *entry = NULL;
+
+ if (!intf->opened && intf->open && intf->open(intf) < 0)
+ return NULL;
+
+ while (itry < session->retry) {
+ ltime = time(NULL);
+
+ if (xmit) {
+
+ if (payload->payload_type == IPMI_PAYLOAD_TYPE_IPMI)
+ {
+ /*
+ * Build an IPMI v1.5 or v2 command
+ */
+ struct ipmi_rq * ipmi_request = payload->payload.ipmi_request.request;
+
+ lprintf(LOG_DEBUG, "");
+ lprintf(LOG_DEBUG, ">> Sending IPMI command payload");
+ lprintf(LOG_DEBUG, ">> netfn : 0x%02x", ipmi_request->msg.netfn);
+ lprintf(LOG_DEBUG, ">> command : 0x%02x", ipmi_request->msg.cmd);
+ lprintf(LOG_DEBUG, ">> data_len: %d", ipmi_request->msg.data_len);
+
+ if (verbose > 1)
+ {
+ char msg[256];
+ uint16_t i; size_t n;
+ sprintf(msg, ">> data : ");
+ n = strlen(msg);
+ for (i = 0; i < ipmi_request->msg.data_len; ++i) {
+ sprintf(&msg[n], "0x%02x ", ipmi_request->msg.data[i]);
+ n += 5;
+ if ((n+5) >= sizeof(msg)) break;
+ }
+ // strcat(msg,"\n");
+ lprintf(LOG_DEBUG, msg);
+ }
+
+
+ /*
+ * If we are presession, and the command is GET CHANNEL AUTHENTICATION
+ * CAPABILITIES, we will build the command in v1.5 format. This is so
+ * that we can ask any server whether it supports IPMI v2 / RMCP+
+ * before we attempt to open a v2.x session.
+ */
+ if ((ipmi_request->msg.netfn == IPMI_NETFN_APP) &&
+ (ipmi_request->msg.cmd == IPMI_GET_CHANNEL_AUTH_CAP) &&
+ // (!ipmi_oem_active(intf, "hp")) &&
+ (session->v2_data.bmc_id == 0)) // jme - check
+ {
+ lprintf(LOG_DEBUG+1, "BUILDING A v1.5 COMMAND");
+ entry = ipmi_lanplus_build_v15_ipmi_cmd(intf, ipmi_request);
+ }
+ else
+ {
+ lprintf(LOG_DEBUG+1, "BUILDING A v2 COMMAND");
+ entry = ipmi_lanplus_build_v2x_ipmi_cmd(intf, ipmi_request);
+ }
+
+ if (entry == NULL) {
+ lprintf(LOG_ERR, "Aborting send command, unable to build");
+ return NULL;
+ }
+
+ msg_data = entry->msg_data;
+ msg_length = entry->msg_len;
+ // entry is freed later for IPMI payloads
+ }
+
+ else if (payload->payload_type == IPMI_PAYLOAD_TYPE_RMCP_OPEN_REQUEST)
+ {
+ lprintf(LOG_DEBUG, ">> SENDING AN OPEN SESSION REQUEST\n");
+ /* assert(session->v2_data.session_state == LANPLUS_STATE_PRESESSION); */
+ if (session->v2_data.session_state != LANPLUS_STATE_PRESESSION) {
+ /* Sometimes state==OPEN_SESSION_SENT(1) */
+ lprintf(LOG_ERR, "lanplus open session_state %x != LANPLUSLANPLUS_STATE_PRESESSION\n",session->v2_data.session_state);
+ return NULL;
+ } /*ARC, removed assert*/
+
+ rv = ipmi_lanplus_build_v2x_msg(intf, /* in */
+ payload, /* in */
+ &msg_length, /* out*/
+ &msg_data, /* out*/
+ 0); /* irrelevant for this msg*/
+ if (rv != 0) return NULL;
+
+ }
+
+ else if (payload->payload_type == IPMI_PAYLOAD_TYPE_RAKP_1)
+ {
+ lprintf(LOG_DEBUG, ">> SENDING A RAKP 1 MESSAGE\n");
+ /* sometimes hit this assert - ARC */
+ // assert(session->v2_data.session_state ==
+ // LANPLUS_STATE_OPEN_SESSION_RECEIEVED);
+ if (session->v2_data.session_state !=
+ LANPLUS_STATE_OPEN_SESSION_RECEIEVED) {
+ lprintf(LOG_ERR, "lanplus rakp1 payload: session_state %x != LANPLUS_STATE_OPEN_SESSION_RECEIEVED\n",session->v2_data.session_state);
+ return NULL;
+ }
+
+ rv = ipmi_lanplus_build_v2x_msg(intf, /* in */
+ payload, /* in */
+ &msg_length, /* out*/
+ &msg_data, /* out*/
+ 0); /* irrelevant for this msg*/
+ if (rv != 0) return NULL;
+
+ }
+
+ else if (payload->payload_type == IPMI_PAYLOAD_TYPE_RAKP_3)
+ {
+ lprintf(LOG_DEBUG, ">> SENDING A RAKP 3 MESSAGE\n");
+ // assert(session->v2_data.session_state ==
+ // LANPLUS_STATE_RAKP_2_RECEIVED);
+ if (session->v2_data.session_state !=
+ LANPLUS_STATE_RAKP_2_RECEIVED) {
+ /* Sometimes state==RAKP_3_SENT(5) */
+ lprintf(LOG_ERR, "lanplus rakp3 payload: session_state %x != LANPLUS_STATE_RAKP_2_RECEIVED, try=%d\n",session->v2_data.session_state,itry);
+ return NULL;
+ }
+
+ rv = ipmi_lanplus_build_v2x_msg(intf, /* in */
+ payload, /* in */
+ &msg_length, /* out*/
+ &msg_data, /* out*/
+ 0); /* irrelevant for this msg*/
+ if (rv != 0) return NULL;
+
+ }
+
+ else if (payload->payload_type == IPMI_PAYLOAD_TYPE_SOL)
+ {
+ lprintf(LOG_DEBUG, ">> SENDING A SOL MESSAGE\n");
+ // assert(session->v2_data.session_state == LANPLUS_STATE_ACTIVE);
+ if (session->v2_data.session_state != LANPLUS_STATE_ACTIVE) {
+ lprintf(LOG_ERR, "lanplus session_state %x != LANPLUS_STATE_ACTIVE, try=%d\n",session->v2_data.session_state, itry);
+ return NULL;
+ } /*ARC, removed assert*/
+
+ rv = ipmi_lanplus_build_v2x_msg(intf, /* in */
+ payload, /* in */
+ &msg_length, /* out*/
+ &msg_data, /* out*/
+ 0); /* irrelevant for this msg*/
+ if (rv != 0) return NULL;
+ }
+
+ else
+ {
+ lprintf(LOG_ERR, "Payload type 0x%0x is unsupported!",
+ payload->payload_type);
+ // assert(0);
+ return NULL;
+ }
+
+
+ if (ipmi_lan_send_packet(intf, msg_data, msg_length) < 0) {
+ lprintf(LOG_ERR, "IPMI LAN send command failed");
+ free(msg_data); /*added in v2.8.5*/
+ return(NULL);
+ }
+ }
+
+ /* if we are set to noanswer we do not expect response */
+ if (intf->noanswer)
+ break;
+
+ lan2_usleep(0,recv_delay); /* wait 100us before doing recv */
+
+ /* Remember our connection state */
+ switch (payload->payload_type)
+ {
+ case IPMI_PAYLOAD_TYPE_RMCP_OPEN_REQUEST:
+ session->v2_data.session_state = LANPLUS_STATE_OPEN_SESSION_SENT;
+ break;
+ case IPMI_PAYLOAD_TYPE_RAKP_1:
+ session->v2_data.session_state = LANPLUS_STATE_RAKP_1_SENT;
+ break;
+ case IPMI_PAYLOAD_TYPE_RAKP_3:
+ session->v2_data.session_state = LANPLUS_STATE_RAKP_3_SENT;
+ break;
+ }
+
+
+ /*
+ * Special case for SOL outbound packets.
+ */
+ if (payload->payload_type == IPMI_PAYLOAD_TYPE_SOL)
+ {
+ if (!payload->payload.sol_packet.packet_sequence_number)
+ {
+ /* We're just sending an ACK. No need to retry. */
+ if (verbose > 2)
+ lprintf(LOG_INFO, "send_payload(SOL,ack) nowait"); /*ARC*/
+ break;
+ }
+ if (verbose > 2)
+ lprintf(LOG_INFO, "send_payload(SOL,timeout=%d)",intf->session->timeout); /*ARC*/
+
+ rsp = ipmi_lanplus_recv_sol(intf); /* Grab the next packet */
+
+ if (sol_response_acks_packet(rsp, payload)) {
+ if (verbose > 2)
+ lprintf(LOG_INFO, /*ARC*/
+ "send_payload(SOL) rsp acks_packet %d",
+ payload->payload.sol_packet.packet_sequence_number);
+ break;
+ }
+
+ else if (is_sol_packet(rsp) && rsp->data_len)
+ {
+ lprintf(LOG_INFO, /*ARC*/
+ "send_payload(SOL,%d,%d), rlen=%d seq=%d, no ack yet",
+ intf->session->timeout,itry,rsp->data_len,
+ payload->payload.sol_packet.packet_sequence_number);
+ /*
+ * We're still waiting for our ACK, but we got
+ * more data from the BMC. Send to handler.
+ */
+ intf->session->sol_data.sol_input_handler(rsp);
+ /* In order to avoid duplicate output, just set data_len to 0 */
+ rsp->data_len = 0; /*added 04/17/08*/
+ if (slow_link) break; /*ARC 09/01/09*/
+ }
+ else {
+ lprintf(LOG_INFO, /*ARC*/
+ "send_payload(SOL,%d,%d) sol_seq=%d rsp=%p no ack",
+ intf->session->timeout,itry,
+ payload->payload.sol_packet.packet_sequence_number,
+ rsp);
+ }
+ }
+
+
+ /* Non-SOL processing */
+ else
+ {
+ lprintf(LOG_INFO,
+ "send_payload(non-SOL) type=%d data",
+ payload->payload_type);
+ rsp = ipmi_lan_poll_recv(intf);
+ if (rsp) {
+ lprintf(LOG_INFO,
+ "send_payload(non-SOL) rsp dlen=%d, rs_seq=%d",
+ rsp->data_len,rsp->session.seq);
+ break;
+ }
+ }
+
+ xmit = ((u_long)(time(NULL) - ltime) >= intf->session->timeout);
+
+ lan2_usleep(0,5000); /*sleep 5.0ms before next try*/
+
+ if (xmit) {
+ /* incremet session timeout each try */
+ intf->session->timeout++;
+ }
+
+ itry++;
+ }
+
+ /* Reset timeout after retry loop completes */
+ intf->session->timeout = lan2_timeout;
+
+ /* IPMI messages are deleted under ipmi_lan_poll_recv() */
+ switch (payload->payload_type) {
+ case IPMI_PAYLOAD_TYPE_RMCP_OPEN_REQUEST:
+ case IPMI_PAYLOAD_TYPE_RAKP_1:
+ case IPMI_PAYLOAD_TYPE_RAKP_3:
+ free(msg_data);
+ break;
+ }
+ return rsp;
+}
+
+
+
+/*
+ * is_sol_partial_ack
+ *
+ * Determine if the response is a partial ACK/NACK that indicates
+ * we need to resend part of our packet.
+ *
+ * returns the number of characters we need to resend, or
+ * 0 if this isn't an ACK or we don't need to resend anything
+ */
+int is_sol_partial_ack(
+ struct ipmi_intf * intf,
+ struct ipmi_v2_payload * v2_payload,
+ struct ipmi_rs * rs)
+{
+ int chars_to_resend = 0;
+
+ if (v2_payload &&
+ rs &&
+ is_sol_packet(rs) &&
+ sol_response_acks_packet(rs, v2_payload) &&
+ (rs->payload.sol_packet.accepted_character_count <
+ v2_payload->payload.sol_packet.character_count))
+ {
+ lprintf(LOG_INFO, "is_sol_partial_ack: count=%d > accepted=%d",
+ v2_payload->payload.sol_packet.character_count,
+ rs->payload.sol_packet.accepted_character_count );
+ if (ipmi_oem_active(intf, "intelplus") &&
+ rs->payload.sol_packet.accepted_character_count == 0)
+ return 0;
+
+ chars_to_resend =
+ v2_payload->payload.sol_packet.character_count -
+ rs->payload.sol_packet.accepted_character_count;
+ }
+
+ return chars_to_resend;
+}
+
+
+
+/*
+ * set_sol_packet_sequence_number
+ */
+static void set_sol_packet_sequence_number(
+ struct ipmi_intf * intf,
+ struct ipmi_v2_payload * v2_payload)
+{
+ /* Keep our sequence number sane */
+ if (intf->session->sol_data.sequence_number > 0x0F)
+ intf->session->sol_data.sequence_number = 1;
+
+ v2_payload->payload.sol_packet.packet_sequence_number =
+ intf->session->sol_data.sequence_number++;
+}
+
+
+
+/*
+ * ipmi_lanplus_send_sol
+ *
+ * Sends a SOL packet.. We handle partial ACK/NACKs from the BMC here.
+ *
+ * Returns a pointer to the SOL ACK we received, or
+ * 0 on failure
+ *
+ */
+struct ipmi_rs *
+ipmi_lanplus_send_sol(
+ struct ipmi_intf * intf,
+ void * v2_in)
+{
+ struct ipmi_v2_payload * v2_payload = v2_in;
+ struct ipmi_rs * rs;
+
+ /*
+ * chars_to_resend indicates either that we got a NACK telling us
+ * that we need to resend some part of our data.
+ */
+ int chars_to_resend = 0;
+
+ v2_payload->payload_type = IPMI_PAYLOAD_TYPE_SOL;
+
+ /*
+ * Payload length is just the length of the character
+ * data here.
+ */
+ v2_payload->payload_length = v2_payload->payload.sol_packet.character_count;
+
+ v2_payload->payload.sol_packet.acked_packet_number = 0; /* NA */
+
+ set_sol_packet_sequence_number(intf, v2_payload);
+
+ v2_payload->payload.sol_packet.accepted_character_count = 0; /* NA */
+
+ rs = ipmi_lanplus_send_payload(intf, v2_payload);
+
+ /* Determine if we need to resend some of our data */
+ chars_to_resend = is_sol_partial_ack(intf, v2_payload, rs);
+
+ if ((verbose > 2) && (chars_to_resend > 0)) { /*show warnings if here*/
+ if (rs == NULL)
+ lprintf(LOG_INFO,"send_sol: nresend=%d no rs",chars_to_resend);
+ else
+ lprintf(LOG_INFO,"send_sol: nresend=%d unavail=%d nack=%d",
+ chars_to_resend,
+ rs->payload.sol_packet.transfer_unavailable,
+ rs->payload.sol_packet.is_nack);
+ }
+
+ while (rs && !rs->payload.sol_packet.transfer_unavailable &&
+ !rs->payload.sol_packet.is_nack &&
+ chars_to_resend)
+ {
+ /*
+ * We first need to handle any new data we might have
+ * received in our NACK
+ */
+ if (rs->data_len)
+ intf->session->sol_data.sol_input_handler(rs);
+
+ set_sol_packet_sequence_number(intf, v2_payload);
+
+ /* Just send the required data */
+ memmove(v2_payload->payload.sol_packet.data,
+ v2_payload->payload.sol_packet.data +
+ rs->payload.sol_packet.accepted_character_count,
+ chars_to_resend);
+
+ v2_payload->payload.sol_packet.character_count = (uint16_t)chars_to_resend;
+
+ v2_payload->payload_length = v2_payload->payload.sol_packet.character_count;
+
+ rs = ipmi_lanplus_send_payload(intf, v2_payload);
+
+ chars_to_resend = is_sol_partial_ack(intf, v2_payload, rs);
+ }
+
+ return rs;
+}
+
+
+
+/*
+ * check_sol_packet_for_new_data
+ *
+ * Determine whether the SOL packet has already been seen
+ * and whether the packet has new data for us.
+ *
+ * This function has the side effect of removing an previously
+ * seen data, and moving new data to the front.
+ *
+ * It also "Remembers" the data so we don't get repeats.
+ *
+ * returns the number of new bytes in the SOL packet
+ */
+static int
+check_sol_packet_for_new_data(
+ struct ipmi_intf * intf,
+ struct ipmi_rs *rsp)
+{
+ static uint8_t last_received_sequence_number = 0;
+ static uint8_t last_received_byte_count = 0;
+ int new_data_size = 0;
+
+
+ if (rsp &&
+ (rsp->session.authtype == IPMI_SESSION_AUTHTYPE_RMCP_PLUS) &&
+ (rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_SOL))
+ {
+ /* Store the data length before we mod it */
+ uint8_t unaltered_data_len = (uint8_t)rsp->data_len;
+
+ lprintf(LOG_INFO,"check_sol_packet_for_new_data: "
+ "rsp dlen=%d rs_seq=%d sol_rseq=%d",
+ rsp->data_len, rsp->session.seq,
+ rsp->payload.sol_packet.packet_sequence_number);
+ if (rsp->payload.sol_packet.packet_sequence_number ==
+ last_received_sequence_number)
+ {
+ if (verbose > 2)
+ lprintf(LOG_INFO,"check_sol: seq=%x retry match len=%d nlast=%d",
+ rsp->payload.sol_packet.packet_sequence_number,
+ rsp->data_len, last_received_byte_count);
+ /*
+ * This is the same as the last packet, but may include
+ * extra data
+ */
+ new_data_size = rsp->data_len - last_received_byte_count;
+
+ if (new_data_size > 0)
+ {
+ /* We have more data to process */
+ memmove(rsp->data,
+ rsp->data +
+ rsp->data_len - new_data_size,
+ new_data_size);
+ }
+
+ rsp->data_len = new_data_size;
+ }
+
+ /*
+ * Remember the data for next round
+ * if non-zero sequence number
+ */
+ if (rsp->payload.sol_packet.packet_sequence_number)
+ {
+ last_received_sequence_number =
+ rsp->payload.sol_packet.packet_sequence_number;
+
+ last_received_byte_count = unaltered_data_len;
+ }
+ else if (rsp->data_len > 0)
+ { /* rsp sol seq is zero, so ignore any data */
+ lprintf(LOG_INFO,"check_sol: rseq=%d rlen=%d ack, zero data",
+ rsp->payload.sol_packet.packet_sequence_number,
+ rsp->data_len);
+ rsp->data_len = 0;
+ }
+ }
+
+
+ return new_data_size;
+}
+
+
+
+/*
+ * ack_sol_packet
+ *
+ * Provided the specified packet looks reasonable, ACK it.
+ */
+static void
+ack_sol_packet(
+ struct ipmi_intf * intf,
+ struct ipmi_rs * rsp)
+{
+ if (rsp &&
+ (rsp->session.authtype == IPMI_SESSION_AUTHTYPE_RMCP_PLUS) &&
+ (rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_SOL) &&
+ (rsp->payload.sol_packet.packet_sequence_number))
+ {
+ struct ipmi_v2_payload ack;
+
+ memset(&ack, 0, sizeof(struct ipmi_v2_payload));
+
+ ack.payload_type = IPMI_PAYLOAD_TYPE_SOL;
+
+ /*
+ * Payload length is just the length of the character
+ * data here.
+ */
+ ack.payload_length = 0;
+
+ /* ACK packets have sequence numbers of 0 */
+ ack.payload.sol_packet.packet_sequence_number = 0;
+
+ ack.payload.sol_packet.acked_packet_number =
+ rsp->payload.sol_packet.packet_sequence_number;
+
+ ack.payload.sol_packet.accepted_character_count = (uint8_t)rsp->data_len;
+
+ if (verbose > 2)
+ lprintf(LOG_INFO,"ack of seq_num 0x%x",rsp->payload.sol_packet.packet_sequence_number);
+ ipmi_lanplus_send_payload(intf, &ack);
+ }
+}
+
+
+
+/*
+ * ipmi_lanplus_recv_sol
+ *
+ * Receive a SOL packet and send an ACK in response.
+ *
+ */
+struct ipmi_rs *
+ipmi_lanplus_recv_sol(struct ipmi_intf * intf)
+{
+ struct ipmi_rs * rsp = ipmi_lan_poll_recv(intf);
+
+ if (rsp && rsp->session.authtype != 0)
+ {
+ ack_sol_packet(intf, rsp);
+
+ /*
+ * Remembers the data sent, and alters the data to just
+ * include the new stuff.
+ */
+ check_sol_packet_for_new_data(intf, rsp);
+ }
+ return rsp;
+}
+
+
+
+/**
+ * ipmi_lanplus_send_ipmi_cmd
+ *
+ * Build a payload request and dispatch it.
+ */
+struct ipmi_rs *
+ipmi_lanplus_send_ipmi_cmd(
+ struct ipmi_intf * intf,
+ struct ipmi_rq * req)
+{
+ struct ipmi_v2_payload v2_payload;
+
+ v2_payload.payload_type = IPMI_PAYLOAD_TYPE_IPMI;
+ // v2_payload.payload_length = 7 + req->msg.data_len; /*initial ++++*/
+ v2_payload.payload.ipmi_request.request = req;
+
+ // if (verbose > 2) lprintf(LOG_INFO,"ipmi cmd payload"); /*++++*/
+ return ipmi_lanplus_send_payload(intf, &v2_payload);
+}
+
+
+/*
+ * ipmi_get_auth_capabilities_cmd
+ *
+ * This command may have to be sent twice. We first ask for the
+ * authentication capabilities with the "request IPMI v2 data bit"
+ * set. If this fails, we send the same command without that bit
+ * set.
+ *
+ * param intf is the initialized (but possibly) pre-session interface
+ * on which we will send the command
+ * param auth_cap [out] will be initialized to hold the Get Channel
+ * Authentication Capabilities return data on success. Its
+ * contents will be undefined on error.
+ *
+ * returns 0 on success
+ * non-zero if we were unable to contact the BMC, or we cannot
+ * get a successful response
+ *
+ */
+static int
+ipmi_get_auth_capabilities_cmd(
+ struct ipmi_intf * intf,
+ struct get_channel_auth_cap_rsp * auth_cap)
+{
+ struct ipmi_rs * rsp;
+ struct ipmi_rq req;
+ uint8_t msg_data[2];
+ uint8_t backupBridgePossible;
+
+ backupBridgePossible = bridgePossible;
+
+ bridgePossible = 0;
+
+ msg_data[0] = IPMI_LAN_CHANNEL_E | 0x80; // Ask for IPMI v2 data as well
+ msg_data[1] = intf->session->privlvl;
+
+ 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 == NULL || rsp->ccode > 0) {
+ /*
+ * It's very possible that this failed because we asked for IPMI
+ * v2 data. Ask again, without requesting IPMI v2 data.
+ */
+ msg_data[0] &= 0x7F;
+
+ rsp = intf->sendrecv(intf, &req);
+
+ if (rsp == NULL) {
+ lprintf(LOG_INFO, "Get Auth Capabilities error");
+ return 1;
+ }
+ if (rsp->ccode > 0) {
+ lprintf(LOG_INFO, "Get Auth Capabilities error: %s",
+ val2str(rsp->ccode, completion_code_vals));
+ return 1;
+ }
+ }
+
+
+ memcpy(auth_cap,
+ rsp->data,
+ sizeof(struct get_channel_auth_cap_rsp));
+
+ bridgePossible = backupBridgePossible;
+
+ return 0;
+}
+
+
+
+static int
+ipmi_close_session_cmd(struct ipmi_intf * intf)
+{
+ struct ipmi_rs * rsp;
+ struct ipmi_rq req;
+ uint8_t msg_data[4];
+ uint32_t bmc_session_lsbf;
+ uint8_t backupBridgePossible;
+
+ if (intf->session->v2_data.session_state != LANPLUS_STATE_ACTIVE)
+ return -1;
+
+ backupBridgePossible = bridgePossible;
+
+ intf->target_addr = IPMI_BMC_SLAVE_ADDR;
+ bridgePossible = 0;
+
+ bmc_session_lsbf = intf->session->v2_data.bmc_id;
+#if WORDS_BIGENDIAN
+ bmc_session_lsbf = BSWAP_32(bmc_session_lsbf);
+#endif
+
+ memcpy(&msg_data, &bmc_session_lsbf, 4);
+
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_APP;
+ req.msg.cmd = 0x3c;
+ req.msg.data = msg_data;
+ req.msg.data_len = 4;
+
+ rsp = intf->sendrecv(intf, &req);
+ if (rsp == NULL) {
+ /* Looks like the session was closed */
+ lprintf(LOG_ERR, "Close Session command failed");
+ return -1;
+ }
+ if (verbose > 2)
+ printbuf(rsp->data, rsp->data_len, "close_session");
+
+ if (rsp->ccode == 0x87) {
+ lprintf(LOG_ERR, "Failed to Close Session: invalid "
+ "session ID %08lx",
+ (long)intf->session->v2_data.bmc_id);
+ return -1;
+ }
+ if (rsp->ccode > 0) {
+ lprintf(LOG_ERR, "Close Session command failed: %s",
+ val2str(rsp->ccode, completion_code_vals));
+ return -1;
+ }
+
+ lprintf(LOG_DEBUG, "Closed Session %08lx\n",
+ (long)intf->session->v2_data.bmc_id);
+
+ bridgePossible = backupBridgePossible;
+
+ return 0;
+}
+
+
+
+/*
+ * ipmi_lanplus_open_session
+ *
+ * Build and send the open session command. See section 13.17 of the IPMI
+ * v2 specification for details.
+ */
+static int
+ipmi_lanplus_open_session(struct ipmi_intf * intf)
+{
+ struct ipmi_v2_payload v2_payload;
+ struct ipmi_session * session = intf->session;
+ uint8_t * msg;
+ struct ipmi_rs * rsp;
+ int rc = 0;
+
+
+ lprintf(LOG_INFO,"ipmi_lanplus_open_session, verbose=%d\n",
+ verbose);
+ /*
+ * Build an Open Session Request Payload
+ */
+ msg = (uint8_t*)malloc(IPMI_OPEN_SESSION_REQUEST_SIZE);
+ if (msg == NULL) {
+ lprintf(LOG_ERR, "lanplus: malloc failure");
+ return -1;
+ }
+
+ memset(msg, 0, IPMI_OPEN_SESSION_REQUEST_SIZE);
+
+ msg[0] = 0; /* Message tag */
+ if (ipmi_oem_active(intf, "intelplus") || session->privlvl != IPMI_SESSION_PRIV_ADMIN)
+ msg[1] = session->privlvl;
+ else
+ msg[1] = 0; /* Give us highest privlg level based on supported algorithms */
+ msg[2] = 0; /* reserved */
+ msg[3] = 0; /* reserved */
+
+ /* Choose our session ID for easy recognition in the packet dump */
+ session->v2_data.console_id = 0xA0A2A3A4;
+ msg[4] = session->v2_data.console_id & 0xff;
+ msg[5] = (session->v2_data.console_id >> 8) & 0xff;
+ msg[6] = (session->v2_data.console_id >> 16) & 0xff;
+ msg[7] = (session->v2_data.console_id >> 24) & 0xff;
+
+
+ if (lanplus_get_requested_ciphers(session->cipher_suite_id,
+ &(session->v2_data.requested_auth_alg),
+ &(session->v2_data.requested_integrity_alg),
+ &(session->v2_data.requested_crypt_alg)))
+ {
+ lprintf(LOG_WARNING, "Unsupported cipher suite ID : %d\n",
+ session->cipher_suite_id);
+ free(msg);
+ return -1;
+ }
+
+
+ /*
+ * Authentication payload
+ */
+ msg[8] = 0; /* specifies authentication payload */
+ msg[9] = 0; /* reserved */
+ msg[10] = 0; /* reserved */
+ msg[11] = 8; /* payload length */
+ msg[12] = session->v2_data.requested_auth_alg;
+ msg[13] = 0; /* reserved */
+ msg[14] = 0; /* reserved */
+ msg[15] = 0; /* reserved */
+
+ /*
+ * Integrity payload
+ */
+ msg[16] = 1; /* specifies integrity payload */
+ msg[17] = 0; /* reserved */
+ msg[18] = 0; /* reserved */
+ msg[19] = 8; /* payload length */
+ msg[20] = session->v2_data.requested_integrity_alg;
+ msg[21] = 0; /* reserved */
+ msg[22] = 0; /* reserved */
+ msg[23] = 0; /* reserved */
+
+ /*
+ * Confidentiality/Encryption payload
+ */
+ msg[24] = 2; /* specifies confidentiality payload */
+ msg[25] = 0; /* reserved */
+ msg[26] = 0; /* reserved */
+ msg[27] = 8; /* payload length */
+ msg[28] = session->v2_data.requested_crypt_alg;
+ msg[29] = 0; /* reserved */
+ msg[30] = 0; /* reserved */
+ msg[31] = 0; /* reserved */
+
+
+ v2_payload.payload_type = IPMI_PAYLOAD_TYPE_RMCP_OPEN_REQUEST;
+ v2_payload.payload_length = IPMI_OPEN_SESSION_REQUEST_SIZE;
+ v2_payload.payload.open_session_request.request = msg;
+
+ rsp = ipmi_lanplus_send_payload(intf, &v2_payload);
+
+ free(msg);
+
+ if (rsp == NULL) {
+ /* failsafe check for Dell PE1955 - ARCress 02/28/07 */
+ lprintf(LOG_WARNING, "Error in open session, no response.\n");
+ return -1;
+ }
+ if (verbose)
+ lanplus_dump_open_session_response(rsp);
+
+
+ if (rsp->payload.open_session_response.rakp_return_code !=
+ IPMI_RAKP_STATUS_NO_ERRORS)
+ {
+ lprintf(LOG_WARNING, "Error in open session response message : %s\n",
+ val2str(rsp->payload.open_session_response.rakp_return_code,
+ ipmi_rakp_return_codes));
+ return -1;
+ }
+ else
+ {
+ if (rsp->payload.open_session_response.console_id !=
+ session->v2_data.console_id) {
+ lprintf(LOG_WARNING, "Warning: Console session ID is not "
+ "what we requested");
+ }
+
+ session->v2_data.max_priv_level =
+ rsp->payload.open_session_response.max_priv_level;
+ session->v2_data.bmc_id =
+ rsp->payload.open_session_response.bmc_id;
+ session->v2_data.auth_alg =
+ rsp->payload.open_session_response.auth_alg;
+ session->v2_data.integrity_alg =
+ rsp->payload.open_session_response.integrity_alg;
+ session->v2_data.crypt_alg =
+ rsp->payload.open_session_response.crypt_alg;
+ session->v2_data.session_state =
+ LANPLUS_STATE_OPEN_SESSION_RECEIEVED;
+
+
+ /*
+ * Verify that we have agreed on a cipher suite
+ */
+ if (rsp->payload.open_session_response.auth_alg !=
+ session->v2_data.requested_auth_alg)
+ {
+ lprintf(LOG_WARNING, "Authentication algorithm 0x%02x is "
+ "not what we requested 0x%02x\n",
+ rsp->payload.open_session_response.auth_alg,
+ session->v2_data.requested_auth_alg);
+ rc = -1;
+ }
+ else if (rsp->payload.open_session_response.integrity_alg !=
+ session->v2_data.requested_integrity_alg)
+ {
+ lprintf(LOG_WARNING, "Integrity algorithm 0x%02x is "
+ "not what we requested 0x%02x\n",
+ rsp->payload.open_session_response.integrity_alg,
+ session->v2_data.requested_integrity_alg);
+ rc = -1;
+ }
+ else if (rsp->payload.open_session_response.crypt_alg !=
+ session->v2_data.requested_crypt_alg)
+ {
+ lprintf(LOG_WARNING, "Encryption algorithm 0x%02x is "
+ "not what we requested 0x%02x\n",
+ rsp->payload.open_session_response.crypt_alg,
+ session->v2_data.requested_crypt_alg);
+ rc = -1;
+ }
+
+ }
+
+ return rc;
+}
+
+
+
+/*
+ * ipmi_lanplus_rakp1
+ *
+ * Build and send the RAKP 1 message as part of the IPMI v2 / RMCP+ session
+ * negotiation protocol. We also read and validate the RAKP 2 message received
+ * from the BMC, here. See section 13.20 of the IPMI v2 specification for
+ * details.
+ *
+ * returns 0 on success
+ * 1 on failure
+ *
+ * Note that failure is only indicated if we have an internal error of
+ * some kind. If we actually get a RAKP 2 message in response to our
+ * RAKP 1 message, any errors will be stored in
+ * session->v2_data.rakp2_return_code and sent to the BMC in the RAKP
+ * 3 message.
+ */
+static int
+ipmi_lanplus_rakp1(struct ipmi_intf * intf)
+{
+ struct ipmi_v2_payload v2_payload;
+ struct ipmi_session * session = intf->session;
+ uint8_t * msg;
+ struct ipmi_rs * rsp;
+ int rc = 0;
+
+ /*
+ * Build a RAKP 1 message
+ */
+ msg = (uint8_t*)malloc(IPMI_RAKP1_MESSAGE_SIZE);
+ if (msg == NULL) {
+ lprintf(LOG_ERR, "lanplus: malloc failure");
+ return 1;
+ }
+ memset(msg, 0, IPMI_RAKP1_MESSAGE_SIZE);
+
+
+ msg[0] = 0; /* Message tag */
+
+ msg[1] = 0; /* reserved */
+ msg[2] = 0; /* reserved */
+ msg[3] = 0; /* reserved */
+
+ /* BMC session ID */
+ msg[4] = session->v2_data.bmc_id & 0xff;
+ msg[5] = (session->v2_data.bmc_id >> 8) & 0xff;
+ msg[6] = (session->v2_data.bmc_id >> 16) & 0xff;
+ msg[7] = (session->v2_data.bmc_id >> 24) & 0xff;
+
+
+ /* We need a 16 byte random number */
+ if (lanplus_rand(session->v2_data.console_rand, 16))
+ {
+ // ERROR;
+ lprintf(LOG_ERR, "ERROR generating random number "
+ "in ipmi_lanplus_rakp1");
+ free(msg);
+ return 1;
+ }
+ memcpy(msg + 8, session->v2_data.console_rand, 16);
+ #if WORDS_BIGENDIAN
+ lanplus_swap(msg + 8, 16);
+ #endif
+
+ if (verbose > 1)
+ printbuf(session->v2_data.console_rand, 16,
+ ">> Console generated random number");
+
+
+ /*
+ * Requested maximum privilege level.
+ */
+ msg[24] = 0x10; /* We will specify a name-only lookup */
+ msg[24] |= session->privlvl;
+ // msg[24] = session->privlvl | session->v2_data.lookupbit; *++++*
+ session->v2_data.requested_role = msg[24];
+ msg[25] = 0; /* reserved */
+ msg[26] = 0; /* reserved */
+
+
+ /* Username specification */
+ msg[27] = (uint8_t)strlen((const char *)session->username);
+ if (msg[27] > IPMI_MAX_USER_NAME_LENGTH)
+ {
+ lprintf(LOG_ERR, "ERROR: user name too long. "
+ "(Exceeds %d characters)",
+ IPMI_MAX_USER_NAME_LENGTH);
+ free(msg);
+ return 1;
+ }
+ memcpy(msg + 28, session->username, msg[27]);
+
+ v2_payload.payload_type = IPMI_PAYLOAD_TYPE_RAKP_1;
+ v2_payload.payload_length =
+ IPMI_RAKP1_MESSAGE_SIZE - (16 - msg[27]);
+ v2_payload.payload.rakp_1_message.message = msg;
+
+ rsp = ipmi_lanplus_send_payload(intf, &v2_payload);
+
+ free(msg);
+
+ if (rsp == NULL)
+ {
+ lprintf(LOG_INFO, "> Error: no response from RAKP 1 message");
+ return 1;
+ }
+
+ session->v2_data.session_state = LANPLUS_STATE_RAKP_2_RECEIVED;
+
+ if (verbose)
+ lanplus_dump_rakp2_message(rsp, session->v2_data.auth_alg);
+
+ if (rsp->payload.rakp2_message.rakp_return_code != IPMI_RAKP_STATUS_NO_ERRORS)
+ {
+ lprintf(LOG_INFO, "RAKP 2 message indicates an error : %s",
+ val2str(rsp->payload.rakp2_message.rakp_return_code,
+ ipmi_rakp_return_codes));
+ rc = 1;
+ }
+
+ else
+ {
+ memcpy(session->v2_data.bmc_rand, rsp->payload.rakp2_message.bmc_rand, 16);
+ memcpy(session->v2_data.bmc_guid, rsp->payload.rakp2_message.bmc_guid, 16);
+
+ if (verbose > 2)
+ printbuf(session->v2_data.bmc_rand, 16, "bmc_rand");
+
+ /*
+ * It is at this point that we have to decode the random number and determine
+ * whether the BMC has authenticated.
+ */
+ if (! lanplus_rakp2_hmac_matches(session,
+ rsp->payload.rakp2_message.key_exchange_auth_code,
+ intf))
+ {
+ /* Error */
+ lprintf(LOG_INFO, "> RAKP 2 HMAC is invalid");
+ session->v2_data.rakp2_return_code = IPMI_RAKP_STATUS_INVALID_INTEGRITY_CHECK_VALUE;
+ rc = 1; /*added 03/28/07*/
+ }
+ else
+ {
+ /* Success */
+ session->v2_data.rakp2_return_code = IPMI_RAKP_STATUS_NO_ERRORS;
+ }
+ }
+
+ return rc;
+}
+
+
+
+/*
+ * ipmi_lanplus_rakp3
+ *
+ * Build and send the RAKP 3 message as part of the IPMI v2 / RMCP+ session
+ * negotiation protocol. We also read and validate the RAKP 4 message received
+ * from the BMC, here. See section 13.20 of the IPMI v2 specification for
+ * details.
+ *
+ * If the RAKP 2 return code is not IPMI_RAKP_STATUS_NO_ERRORS, we will
+ * exit with an error code immediately after sendint the RAKP 3 message.
+ *
+ * param intf is the intf that holds all the state we are concerned with
+ *
+ * returns 0 on success
+ * 1 on failure
+ */
+static int
+ipmi_lanplus_rakp3(struct ipmi_intf * intf)
+{
+ struct ipmi_v2_payload v2_payload;
+ struct ipmi_session * session = intf->session;
+ uint8_t * msg;
+ struct ipmi_rs * rsp;
+
+ if (session->v2_data.session_state != LANPLUS_STATE_RAKP_2_RECEIVED) {
+ lprintf(LOG_ERR, "lanplus: state %d not RAKP2_RECEIVED",
+ session->v2_data.session_state);
+ return 1; /*was assert*/
+ }
+
+ /*
+ * Build a RAKP 3 message
+ */
+ msg = (uint8_t*)malloc(IPMI_RAKP3_MESSAGE_MAX_SIZE);
+ if (msg == NULL) {
+ lprintf(LOG_ERR, "lanplus: malloc failure");
+ return 1;
+ }
+ memset(msg, 0, IPMI_RAKP3_MESSAGE_MAX_SIZE);
+
+ msg[0] = 0; /* Message tag */
+ msg[1] = session->v2_data.rakp2_return_code;
+
+ msg[2] = 0; /* reserved */
+ msg[3] = 0; /* reserved */
+
+ /* BMC session ID */
+ msg[4] = session->v2_data.bmc_id & 0xff;
+ msg[5] = (session->v2_data.bmc_id >> 8) & 0xff;
+ msg[6] = (session->v2_data.bmc_id >> 16) & 0xff;
+ msg[7] = (session->v2_data.bmc_id >> 24) & 0xff;
+
+ v2_payload.payload_type = IPMI_PAYLOAD_TYPE_RAKP_3;
+ v2_payload.payload_length = 8;
+ v2_payload.payload.rakp_3_message.message = msg;
+
+ /*
+ * If the rakp2 return code indicates and error, we don't have to
+ * generate an authcode or session integrity key. In that case, we
+ * are simply sending a RAKP 3 message to indicate to the BMC that the
+ * RAKP 2 message caused an error.
+ */
+ if (session->v2_data.rakp2_return_code == IPMI_RAKP_STATUS_NO_ERRORS)
+ {
+ uint32_t auth_length;
+
+ if (lanplus_generate_rakp3_authcode(msg + 8, session, &auth_length, intf))
+ {
+ /* Error */
+ lprintf(LOG_INFO, "> Error generating RAKP 3 authcode");
+ free(msg);
+ return 1;
+ }
+ else
+ {
+ /* Success */
+ v2_payload.payload_length += (uint16_t)auth_length;
+ }
+
+ /* Generate our Session Integrity Key, K1, and K2 */
+ if (lanplus_generate_sik(session))
+ {
+ /* Error */
+ lprintf(LOG_INFO, "> Error generating session integrity key");
+ free(msg);
+ return 1;
+ }
+ else if (lanplus_generate_k1(session))
+ {
+ /* Error */
+ lprintf(LOG_INFO, "> Error generating K1 key");
+ free(msg);
+ return 1;
+ }
+ else if (lanplus_generate_k2(session))
+ {
+ /* Error */
+ lprintf(LOG_INFO, "> Error generating K2 key");
+ free(msg);
+ return 1;
+ }
+ }
+
+
+ rsp = ipmi_lanplus_send_payload(intf, &v2_payload);
+
+ free(msg);
+
+ if (session->v2_data.rakp2_return_code != IPMI_RAKP_STATUS_NO_ERRORS)
+ {
+ /*
+ * If the previous RAKP 2 message received was deemed erroneous,
+ * we have nothing else to do here. We only sent the RAKP 3 message
+ * to indicate to the BMC that the RAKP 2 message failed.
+ */
+ lprintf(LOG_INFO, "> Error: RAKP2 return code %d",
+ session->v2_data.rakp2_return_code);
+ return 1;
+ }
+ else if (rsp == NULL)
+ {
+ lprintf(LOG_INFO, "> Error: no response from RAKP 3 message");
+ return 1;
+ }
+
+
+ /*
+ * We have a RAKP 4 message to chew on.
+ */
+ if (verbose)
+ lanplus_dump_rakp4_message(rsp, session->v2_data.auth_alg);
+
+
+ if (rsp->payload.open_session_response.rakp_return_code != IPMI_RAKP_STATUS_NO_ERRORS)
+ {
+ lprintf(LOG_INFO, "RAKP 4 message indicates an error : %s",
+ val2str(rsp->payload.rakp4_message.rakp_return_code,
+ ipmi_rakp_return_codes));
+ return 1;
+ }
+
+ else
+ {
+ /* Validate the authcode */
+ if (lanplus_rakp4_hmac_matches(session,
+ rsp->payload.rakp4_message.integrity_check_value,
+ intf))
+ {
+ /* Success */
+ session->v2_data.session_state = LANPLUS_STATE_ACTIVE;
+ }
+ else
+ {
+ /* Error */
+ lprintf(LOG_INFO, "> RAKP 4 message has invalid integrity check value");
+ return 1;
+ }
+ }
+
+ intf->abort = 0;
+ return 0;
+}
+
+
+
+/**
+ * ipmi_lan_close
+ */
+void
+ipmi_lanplus_close(struct ipmi_intf * intf)
+{
+ if (!intf->abort)
+ ipmi_close_session_cmd(intf);
+
+ if (intf->fd != SockInvalid) {
+#ifdef WIN32
+ closesocket(intf->fd);
+ WSACleanup();
+#else
+ close(intf->fd);
+#endif
+ intf->fd = 0;
+ }
+
+ ipmi_req_clear_entries();
+
+ if (intf->session)
+ free(intf->session);
+
+ intf->session = NULL;
+ intf->opened = 0;
+}
+
+
+
+static int
+ipmi_set_session_privlvl_cmd(struct ipmi_intf * intf)
+{
+ struct ipmi_rs * rsp;
+ struct ipmi_rq req;
+ uint8_t backupBridgePossible;
+ uint8_t privlvl = intf->session->privlvl;
+
+ if (privlvl <= IPMI_SESSION_PRIV_USER)
+ return 0; /* no need to set higher */
+
+ backupBridgePossible = bridgePossible;
+
+ bridgePossible = 0;
+
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_APP;
+ req.msg.cmd = 0x3b;
+ req.msg.data = &privlvl;
+ req.msg.data_len = 1;
+
+ rsp = intf->sendrecv(intf, &req);
+ if (rsp == NULL) {
+ lprintf(LOG_ERR, "Set Session Privilege Level to %s failed",
+ val2str(privlvl, ipmi_privlvl_vals));
+ return -1;
+ }
+ if (verbose > 2)
+ printbuf(rsp->data, rsp->data_len, "set_session_privlvl");
+
+ if (rsp->ccode > 0) {
+ lprintf(LOG_ERR, "Set Session Privilege Level to %s failed: %s",
+ val2str(privlvl, ipmi_privlvl_vals),
+ val2str(rsp->ccode, completion_code_vals));
+ return -1;
+ }
+
+ lprintf(LOG_DEBUG, "Set Session Privilege Level to %s\n",
+ val2str(rsp->data[0], ipmi_privlvl_vals));
+
+ bridgePossible = backupBridgePossible;
+
+ return 0;
+}
+
+/**
+ * ipmi_lanplus_open
+ */
+int
+ipmi_lanplus_open(struct ipmi_intf * intf)
+{
+ int rc;
+ struct get_channel_auth_cap_rsp auth_cap;
+ SOCKADDR_T addr;
+ socklen_t addrlen;
+ struct ipmi_session *session;
+#ifdef HAVE_IPV6
+ struct addrinfo hints;
+ struct addrinfo *result, *rp;
+ char service[NI_MAXSERV];
+#else
+ char *temp;
+#endif
+
+ if (!intf || !intf->session)
+ return -1;
+ session = intf->session;
+
+
+ if (!session->port)
+ session->port = IPMI_LANPLUS_PORT;
+ if (!session->privlvl)
+ session->privlvl = IPMI_SESSION_PRIV_ADMIN;
+ if (!session->timeout)
+ session->timeout = lan2_timeout; /*default timeout*/
+ else lan2_timeout = session->timeout; /*set by caller*/
+ if (!session->retry)
+ session->retry = IPMI_LAN_RETRY;
+
+ if (session->hostname == NULL || strlen((const char *)session->hostname) == 0) {
+ lprintf(LOG_ERR, "No hostname specified!");
+ return -1;
+ }
+
+ intf->abort = 1;
+
+
+ /* Setup our lanplus session state */
+ session->v2_data.session_state = LANPLUS_STATE_PRESESSION;
+ session->v2_data.auth_alg = IPMI_AUTH_RAKP_NONE;
+ session->v2_data.crypt_alg = IPMI_CRYPT_NONE;
+ session->v2_data.console_id = 0x00;
+ session->v2_data.bmc_id = 0x00;
+ session->sol_data.sequence_number = 1;
+ //session->sol_data.last_received_sequence_number = 0;
+ //session->sol_data.last_received_byte_count = 0;
+ memset(session->v2_data.sik, 0, sizeof(session->v2_data.sik));
+ session->v2_data.sik_len = 0;
+
+ /* Kg is set in ipmi_intf */
+ //memset(session->v2_data.kg, 0, IPMI_KG_BUFFER_SIZE);
+
+#ifdef WIN32
+ {
+ DWORD rvl;
+ rvl = WSAStartup(0x0202,&lan2_ws);
+ if (rvl != 0) {
+ lprintf(LOG_ERR, "WSAStartup(2.2) error %ld, try 1.1\n", rvl);
+ rvl = WSAStartup(0x0101,&lan2_ws);
+ if (rvl != 0) {
+ lprintf(LOG_ERR, "WSAStartup(1.1) error %ld\n", rvl);
+ return((int)rvl);
+ }
+ }
+ }
+#endif
+
+#ifdef HAVE_IPV6
+ session->addrlen = 0;
+ memset(&session->addr, 0, sizeof(session->addr));
+ memset(&addr, 0, sizeof(addr));
+ sprintf(service, "%d", session->port);
+ /* Obtain address(es) matching host/port */
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
+ hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */
+ hints.ai_flags = my_ai_flags;
+ hints.ai_protocol = IPPROTO_UDP; /* */
+
+ rc = getaddrinfo((char *)session->hostname, service, &hints, &result);
+ if (rc != 0) {
+ lprintf(LOG_ERR, "Address lookup for %s failed with %d",
+ session->hostname,rc);
+ return -1;
+ }
+
+ /* getaddrinfo() returns a list of address structures.
+ * Try each address until we successfully connect(2).
+ */
+ for (rp = result; rp != NULL; rp = rp->ai_next) {
+ intf->fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
+ if (intf->fd == -1) continue;
+ /* valid protocols are IPPROTO_UDP, IPPROTO_IPV6 */
+ if (rp->ai_protocol == IPPROTO_TCP) continue; /*IPMI != TCP*/
+ lprintf(LOG_DEBUG, "lanplus socket(%d,%d,%d), connect(%d)",
+ rp->ai_family, rp->ai_socktype, rp->ai_protocol,
+ intf->fd );
+ if (connect(intf->fd, rp->ai_addr, rp->ai_addrlen) != -1) {
+ lprintf(LOG_DEBUG, "lanplus connect ok, addrlen=%d size=%d",
+ rp->ai_addrlen,sizeof(addr));
+ addrlen = rp->ai_addrlen;
+ memcpy(&addr, rp->ai_addr, addrlen);
+ // memcpy(&session->addr, rp->ai_addr, rp->ai_addrlen);
+ session->addrlen = rp->ai_addrlen;
+ break; /* Success */
+ }
+ close(intf->fd);
+ intf->fd = -1;
+ }
+ freeaddrinfo(result); /* Done with addrinfo */
+ if (intf->fd < 0) {
+ lperror(LOG_ERR, "Connect to %s failed",
+ session->hostname);
+ intf->close(intf);
+ return -1;
+ }
+#else
+ /* open port to BMC via ipv4 */
+ addrlen = sizeof(struct sockaddr_in);
+ memset(&addr, 0, addrlen);
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons((uint16_t)session->port);
+
+#ifdef WIN32
+ rc = -1;
+#else
+ rc = inet_pton(AF_INET, (const char *)session->hostname, &addr.sin_addr);
+#endif
+ if (rc <= 0) {
+ struct hostent *host = gethostbyname((const char *)session->hostname);
+ if (host == NULL) {
+ lprintf(LOG_ERR, "Address lookup for %s failed",
+ session->hostname);
+ return -1;
+ }
+ addr.sin_family = host->h_addrtype;
+ memcpy(&addr.sin_addr, host->h_addr, host->h_length);
+ }
+
+ lprintf(LOG_DEBUG, "IPMI LAN host %s port %d",
+ session->hostname, ntohs(addr.sin_port));
+
+ intf->fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if (intf->fd == SockInvalid) {
+ lperror(LOG_ERR, "Socket failed");
+ return -1;
+ }
+
+
+ /* connect to UDP socket so we get async errors */
+ rc = connect(intf->fd, (struct sockaddr *)&addr, addrlen);
+ if (rc < 0) {
+ lperror(LOG_ERR, "Connect failed");
+ intf->close(intf);
+ return -1;
+ }
+#endif
+
+ intf->opened = 1;
+
+
+ /*
+ * Make sure the BMC supports IPMI v2 / RMCP+
+ *
+ * I'm not sure why we accept a failure for the first call
+ */
+ if (ipmi_get_auth_capabilities_cmd(intf, &auth_cap)) {
+ lan2_usleep(1,0);
+ if (ipmi_get_auth_capabilities_cmd(intf, &auth_cap))
+ {
+ lprintf(LOG_INFO, "Error issuing Get Channel "
+ "Authentication Capabilies request");
+ goto fail;
+ }
+ }
+
+ if (! auth_cap.v20_data_available)
+ {
+ lprintf(LOG_INFO, "This BMC does not support IPMI v2 / RMCP+");
+ goto fail;
+ }
+
+
+ /*
+ * Open session
+ */
+ if (ipmi_lanplus_open_session(intf)){
+ intf->close(intf);
+ goto fail;
+ }
+
+ /*
+ * RAKP 1
+ */
+ if (ipmi_lanplus_rakp1(intf)){
+ lprintf(LOG_ERROR,"LANPLUS error in RAKP1");
+ intf->close(intf);
+ goto fail;
+ }
+
+
+ /*
+ * RAKP 3
+ */
+ if (ipmi_lanplus_rakp3(intf)){
+ lprintf(LOG_ERROR,"LANPLUS error in RAKP3");
+ intf->close(intf);
+ goto fail;
+ }
+
+
+ lprintf(LOG_DEBUG, "IPMIv2 / RMCP+ SESSION OPENED SUCCESSFULLY\n");
+
+ bridgePossible = 1;
+
+ rc = ipmi_set_session_privlvl_cmd(intf);
+ if (rc < 0) {
+ lprintf(LOG_ERROR,"LANPLUS error in set_session_privlvl");
+ intf->close(intf);
+ goto fail;
+ }
+
+#ifdef HAVE_IPV6
+ lan2_nodename[0] = 0;
+ lprintf(LOG_ERROR,"Connected to node %s\n", session->hostname);
+#else
+#ifdef WIN32
+ /* check for ws2_32.lib(getnameinfo) resolution */
+ lan2_nodename[0] = 0;
+#else
+ rc = getnameinfo((struct sockaddr *)&addr, sizeof(struct sockaddr_in),
+ lan2_nodename,sizeof(lan2_nodename), NULL,0,0);
+ if (rc != 0) {
+ lprintf(LOG_DEBUG, "LANPLUS: getnameinfo rv = %d\n",rc);
+ lan2_nodename[0] = 0;
+ }
+#endif
+ temp = inet_ntoa(addr.sin_addr);
+ lprintf(LOG_ERROR,"Connected to node %s %s\n",lan2_nodename,temp);
+#endif
+ return (int)(intf->fd);
+
+fail:
+ lprintf(LOG_ERR, "Error: Unable to establish IPMI v2 / RMCP+ session");
+ intf->opened = 0;
+ return -1;
+}
+
+
+
+void test_crypt1(void)
+{
+ uint8_t key[] =
+ {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,
+ 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14};
+
+ uint16_t bytes_encrypted;
+ uint16_t bytes_decrypted;
+ uint8_t decrypt_buffer[1000];
+ uint8_t encrypt_buffer[1000];
+
+ uint8_t data[] =
+ {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+ 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10,
+ 0x11, 0x12};
+
+ printbuf(data, sizeof(data), "original data");
+
+ if (lanplus_encrypt_payload(IPMI_CRYPT_AES_CBC_128,
+ key,
+ data,
+ sizeof(data),
+ encrypt_buffer,
+ &bytes_encrypted))
+ {
+ lprintf(LOG_ERR, "Encrypt test failed");
+ assert(0); /*assert for testing*/
+ }
+ printbuf(encrypt_buffer, bytes_encrypted, "encrypted payload");
+
+
+ if (lanplus_decrypt_payload(IPMI_CRYPT_AES_CBC_128,
+ key,
+ encrypt_buffer,
+ bytes_encrypted,
+ decrypt_buffer,
+ &bytes_decrypted))
+ {
+ lprintf(LOG_ERR, "Decrypt test failed\n");
+ assert(0); /*assert for testing*/
+ }
+ printbuf(decrypt_buffer, bytes_decrypted, "decrypted payload");
+
+ lprintf(LOG_DEBUG, "\nDone testing the encrypt/decyrpt methods!\n");
+ exit(0);
+}
+
+
+
+void test_crypt2(void)
+{
+ uint8_t key[] =
+ {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,
+ 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14};
+ uint8_t iv[] =
+ {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,
+ 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14};
+ uint8_t data[8] = "12345678";
+
+ uint8_t encrypt_buffer[1000];
+ uint8_t decrypt_buffer[1000];
+ uint32_t bytes_encrypted;
+ uint32_t bytes_decrypted;
+ int len;
+
+ len = (int)strlen((const char *)data),
+ printbuf((const uint8_t *)data, len, "input data");
+
+ lanplus_encrypt_aes_cbc_128(iv, key,
+ data, (uint32_t)len,
+ encrypt_buffer,
+ &bytes_encrypted);
+ printbuf((const uint8_t *)encrypt_buffer, bytes_encrypted, "encrypt_buffer");
+
+ lanplus_decrypt_aes_cbc_128(iv, key,
+ encrypt_buffer,
+ bytes_encrypted,
+ decrypt_buffer,
+ &bytes_decrypted);
+ printbuf((const uint8_t *)decrypt_buffer, bytes_decrypted, "decrypt_buffer");
+
+ lprintf(LOG_INFO, "\nDone testing the encrypt/decyrpt methods!\n");
+ exit(0);
+}
+
+
+/**
+ * send a get device id command to keep session active
+ */
+static int
+ipmi_lanplus_keepalive(struct ipmi_intf * intf)
+{
+ struct ipmi_rs * rsp;
+ struct ipmi_rq req;
+
+ if (!intf->opened)
+ return 0;
+
+ // printf("lanplus_keepalive called\n"); /*++++*/
+ req.msg.netfn = IPMI_NETFN_APP;
+ req.msg.cmd = 0x01; /*GetDeviceID*/
+ req.msg.data_len = 0;
+ rsp = intf->sendrecv(intf, &req);
+ while (rsp != NULL && is_sol_packet(rsp)) {
+ /* rsp was SOL data instead of our answer */
+ /* since it didn't go through the sol recv, do sol recv stuff here */
+ // printf( "lanplus_keepalive got SOL rsp\n"); /*++++*/
+ ack_sol_packet(intf, rsp);
+ check_sol_packet_for_new_data(intf, rsp);
+ // printf( "lanplus_keepalive SOL data len %d\n",rsp->data_len); /*++++*/
+ if (rsp->data_len)
+ intf->session->sol_data.sol_input_handler(rsp);
+ rsp = ipmi_lan_poll_recv(intf);
+ if (rsp == NULL) /* the get device id answer never got back, but retry mechanism was bypassed by SOL data */
+ return 0; /* so get device id command never returned, the connection is still alive */
+ }
+
+ if (rsp == NULL)
+ return -1;
+ if (rsp->ccode > 0)
+ return -1;
+
+ return 0;
+}
+
+
+/**
+ * ipmi_lanplus_setup
+ */
+static int ipmi_lanplus_setup(struct ipmi_intf * intf)
+{
+
+ if (lanplus_seed_prng(16)) {
+ lprintf(LOG_ERR, "lanplus_seed_prng failure");
+ return -1;
+ }
+
+ intf->session = malloc(sizeof(struct ipmi_session));
+ if (intf->session == NULL) {
+ lprintf(LOG_ERR, "lanplus: malloc failure");
+ return -1;
+ }
+ memset(intf->session, 0, sizeof(struct ipmi_session));
+ return 0;
+}
+
+/* end of lanplus.c */
diff --git a/lib/lanplus/lanplus.h b/lib/lanplus/lanplus.h
new file mode 100644
index 0000000..f9ad7dd
--- /dev/null
+++ b/lib/lanplus/lanplus.h
@@ -0,0 +1,135 @@
+/*
+ * 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.
+ */
+
+#ifndef IPMI_LANPLUS_H
+#define IPMI_LANPLUS_H
+
+#include <ipmitool/ipmi.h>
+#include <openssl/sha.h>
+
+#define IPMI_LANPLUS_PORT 0x26f
+
+/*
+ * RAKP return codes. These values come from table 13-15 of the IPMI v2
+ * specification.
+ */
+#define IPMI_RAKP_STATUS_NO_ERRORS 0x00
+#define IPMI_RAKP_STATUS_INSUFFICIENT_RESOURCES_FOR_SESSION 0x01
+#define IPMI_RAKP_STATUS_INVALID_SESSION_ID 0x02
+#define IPMI_RAKP_STATUS_INVALID_PAYLOAD_TYPE 0x03
+#define IPMI_RAKP_STATUS_INVALID_AUTHENTICATION_ALGORITHM 0x04
+#define IPMI_RAKP_STATUS_INVALID_INTEGRITTY_ALGORITHM 0x05
+#define IPMI_RAKP_STATUS_NO_MATCHING_AUTHENTICATION_PAYLOAD 0x06
+#define IPMI_RAKP_STATUS_NO_MATCHING_INTEGRITY_PAYLOAD 0x07
+#define IPMI_RAKP_STATUS_INACTIVE_SESSION_ID 0x08
+#define IPMI_RAKP_STATUS_INVALID_ROLE 0x09
+#define IPMI_RAKP_STATUS_UNAUTHORIZED_ROLE_REQUESTED 0x0A
+#define IPMI_RAKP_STATUS_INSUFFICIENT_RESOURCES_FOR_ROLE 0x0B
+#define IPMI_RAKP_STATUS_INVALID_NAME_LENGTH 0x0C
+#define IPMI_RAKP_STATUS_UNAUTHORIZED_NAME 0x0D
+#define IPMI_RAKP_STATUS_UNAUTHORIZED_GUID 0x0E
+#define IPMI_RAKP_STATUS_INVALID_INTEGRITY_CHECK_VALUE 0x0F
+#define IPMI_RAKP_STATUS_INVALID_CONFIDENTIALITY_ALGORITHM 0x10
+#define IPMI_RAKP_STATUS_NO_CIPHER_SUITE_MATCH 0x11
+#define IPMI_RAKP_STATUS_ILLEGAL_PARAMTER 0x12
+
+
+#define IPMI_LAN_CHANNEL_1 0x07
+#define IPMI_LAN_CHANNEL_2 0x06
+#define IPMI_LAN_CHANNEL_E 0x0e
+
+#define IPMI_LAN_TIMEOUT 1
+#define IPMI_LAN_RETRY 4
+
+#define IPMI_PRIV_CALLBACK 1
+#define IPMI_PRIV_USER 2
+#define IPMI_PRIV_OPERATOR 3
+#define IPMI_PRIV_ADMIN 4
+#define IPMI_PRIV_OEM 5
+
+
+#define IPMI_CRYPT_AES_CBC_128_BLOCK_SIZE 0x10
+
+
+/* Session message offsets, from table 13-8 of the v2 specification */
+#define IPMI_LANPLUS_OFFSET_AUTHTYPE 0x04
+#define IPMI_LANPLUS_OFFSET_PAYLOAD_TYPE 0x05
+#define IPMI_LANPLUS_OFFSET_SESSION_ID 0x06
+#define IPMI_LANPLUS_OFFSET_SEQUENCE_NUM 0x0A
+#define IPMI_LANPLUS_OFFSET_PAYLOAD_SIZE 0x0E
+#define IPMI_LANPLUS_OFFSET_PAYLOAD 0x10
+
+
+#define IPMI_GET_CHANNEL_AUTH_CAP 0x38
+
+/*
+ * Do not change these unless you understand how they interact.
+ * Note:
+ * OpenSSL 0.9.7: #define EVP_MAX_MD_SIZE (16+20) // The SSLv3 md5+sha1 type
+ * OpenSSL 0.9.8: #define EVP_MAX_MD_SIZE 64 // longest known is SHA512
+ */
+#define IPMI_MAX_INTEGRITY_PAD_SIZE EVP_MAX_MD_SIZE
+// HMAC_SHA256_128: 16 HMAC_SHA1_96: 12 HMAC_MD5: 16 MD5: 16
+#define IPMI_MAX_AUTH_CODE_SIZE EVP_MAX_MD_SIZE // must be at least 32.
+#define IPMI_MAX_MAC_SIZE EVP_MAX_MD_SIZE /* The largest mac we ever expect to generate */
+#define IPMI_MAX_CONF_HEADER_SIZE 0x20
+#define IPMI_MAX_PAYLOAD_SIZE 0xFFFF /* Includes confidentiality header/trailer */
+#define IPMI_MAX_CONF_TRAILER_SIZE 0x20
+
+#define IPMI_REQUEST_MESSAGE_SIZE 0x07
+#define IPMI_SHA1_AUTHCODE_SIZE 12
+#define IPMI_HMAC_MD5_AUTHCODE_SIZE 16
+#define IPMI_MD5_AUTHCODE_SIZE 16
+#define IPMI_HMAC_SHA256_AUTHCODE_SIZE 16
+#define SHA256_DIGEST_LENGTH 32 /*may appear in openssl/sha.h later*/
+
+/*
+ *This is accurate, as long as we're only passing 1 auth algorithm,
+ * one integrity algorithm, and 1 encyrption alogrithm
+ */
+#define IPMI_OPEN_SESSION_REQUEST_SIZE 32
+#define IPMI_RAKP1_MESSAGE_SIZE 44
+#define IPMI_RAKP3_MESSAGE_MAX_SIZE (8+EVP_MAX_MD_SIZE)
+
+#define IPMI_MAX_USER_NAME_LENGTH 16
+
+extern const struct valstr ipmi_privlvl_vals[];
+extern const struct valstr ipmi_authtype_vals[];
+
+extern struct ipmi_intf ipmi_lanplus_intf;
+
+struct ipmi_rs * ipmi_lan_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req);
+int ipmi_lanplus_open(struct ipmi_intf * intf);
+void ipmi_lanplus_close(struct ipmi_intf * intf);
+int ipmiv2_lan_ping(struct ipmi_intf * intf);
+
+#endif /*IPMI_LAN_H*/
diff --git a/lib/lanplus/lanplus_crypt.c b/lib/lanplus/lanplus_crypt.c
new file mode 100644
index 0000000..7f3095e
--- /dev/null
+++ b/lib/lanplus/lanplus_crypt.c
@@ -0,0 +1,1038 @@
+/*
+ * 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.
+ */
+
+#include <assert.h>
+#include <string.h>
+#if defined(HAVE_CONFIG_H)
+# include <config.h>
+#endif
+#include <ipmitool/bswap.h>
+#include <ipmitool/log.h>
+#include "lanplus.h"
+#include "lanplus_crypt.h"
+#include "lanplus_crypt_impl.h"
+
+/*
+ * lanplus_rakp2_hmac_matches
+ *
+ * param session holds all the state data that we need to generate the hmac
+ * param hmac is the HMAC sent by the BMC in the RAKP 2 message
+ *
+ * The HMAC was generated [per RFC2404] from :
+ *
+ * SIDm - Remote console session ID
+ * SIDc - BMC session ID
+ * Rm - Remote console random number
+ * Rc - BMC random number
+ * GUIDc - BMC guid
+ * ROLEm - Requested privilege level (entire byte)
+ * ULENGTHm - Username length
+ * <UNAMEm> - Username (absent for null user names)
+ *
+ * generated by using Kuid. I am aware that the subscripts on the values
+ * look backwards, but that's the way they are written in the specification.
+ *
+ * If the authentication algorithm is IPMI_AUTH_RAKP_NONE, we return success.
+ *
+ * return 0 on success (the authcode matches)
+ * 1 on failure (the authcode does not match)
+ */
+int lanplus_rakp2_hmac_matches(const struct ipmi_session * session,
+ const uint8_t * bmc_mac,
+ struct ipmi_intf * intf)
+{
+ uint8_t * buffer;
+ int bufferLength, i;
+ uint8_t mac[EVP_MAX_MD_SIZE];
+ uint32_t macLength;
+
+ uint32_t SIDm_lsbf, SIDc_lsbf;
+
+ if (session->v2_data.auth_alg == IPMI_AUTH_RAKP_NONE)
+ return 1;
+
+ /* We don't yet support other algorithms (was assert) */
+ if ((session->v2_data.auth_alg != IPMI_AUTH_RAKP_HMAC_SHA1) &&
+ (session->v2_data.auth_alg != IPMI_AUTH_RAKP_HMAC_MD5) &&
+ (session->v2_data.auth_alg != IPMI_AUTH_RAKP_HMAC_SHA256)) {
+ printf("Error, unsupported rakp2 auth alg %d\n",
+ session->v2_data.auth_alg);
+ return 1;
+ }
+
+ bufferLength =
+ 4 + /* SIDm */
+ 4 + /* SIDc */
+ 16 + /* Rm */
+ 16 + /* Rc */
+ 16 + /* GUIDc */
+ 1 + /* ROLEm */
+ 1 + /* ULENGTHm */
+ (int)strlen((const char *)session->username); /* optional */
+
+ buffer = malloc(bufferLength);
+ if (buffer == NULL) {
+ lprintf(LOG_ERR, "lanplus: malloc failure");
+ return 1;
+ }
+
+ /*
+ * Fill the buffer. I'm assuming that we're using the LSBF representation of the
+ * multibyte numbers in use.
+ */
+
+ /* SIDm */
+ SIDm_lsbf = session->v2_data.console_id;
+ #if WORDS_BIGENDIAN
+ SIDm_lsbf = BSWAP_32(SIDm_lsbf);
+ #endif
+
+ memcpy(buffer, &SIDm_lsbf, 4);
+
+ /* SIDc */
+ SIDc_lsbf = session->v2_data.bmc_id;
+ #if WORDS_BIGENDIAN
+ SIDc_lsbf = BSWAP_32(SIDc_lsbf);
+ #endif
+ memcpy(buffer + 4, &SIDc_lsbf, 4);
+
+ /* Rm */
+ #if WORDS_BIGENDIAN
+ for (i = 0; i < 16; ++i)
+ buffer[8 + i] = session->v2_data.console_rand[16 - 1 - i];
+ #else
+ for (i = 0; i < 16; ++i)
+ buffer[8 + i] = session->v2_data.console_rand[i];
+ #endif
+
+ /* Rc */
+ #if WORDS_BIGENDIAN
+ for (i = 0; i < 16; ++i)
+ buffer[24 + i] = session->v2_data.bmc_rand[16 - 1 - i];
+ #else
+ for (i = 0; i < 16; ++i)
+ buffer[24 + i] = session->v2_data.bmc_rand[i];
+ #endif
+
+ /* GUIDc */
+ #if WORDS_BIGENDIAN
+ for (i = 0; i < 16; ++i)
+ buffer[40 + i] = session->v2_data.bmc_guid[16 - 1 - i];
+ #else
+ for (i = 0; i < 16; ++i)
+ buffer[40 + i] = session->v2_data.bmc_guid[i];
+ #endif
+
+ /* ROLEm */
+ buffer[56] = session->v2_data.requested_role;
+
+ /* ULENGTHm */
+ buffer[57] = (uint8_t)strlen((const char *)session->username);
+
+ /* UserName [optional] */
+ for (i = 0; i < buffer[57]; ++i)
+ buffer[58 + i] = session->username[i];
+
+ if (verbose > 2)
+ {
+ lprintf(LOG_DEBUG,"rakp2 mac input buffer (%d bytes)", bufferLength);
+ }
+
+ /*
+ * The buffer is complete. Let's hash.
+ */
+ lanplus_HMAC(session->v2_data.auth_alg,
+ session->authcode,
+ IPMI_AUTHCODE_BUFFER_SIZE,
+ buffer,
+ bufferLength,
+ mac,
+ &macLength);
+
+ free(buffer);
+
+
+ if (verbose > 2)
+ {
+ printbuf(mac, macLength, ">> rakp2 mac as computed by the remote console");
+ }
+
+ return (memcmp(bmc_mac, mac, macLength) == 0);
+}
+
+
+
+/*
+ * lanplus_rakp4_hmac_matches
+ *
+ * param session holds all the state data that we need to generate the hmac
+ * param hmac is the HMAC sent by the BMC in the RAKP 4 message
+ *
+ * The HMAC was generated [per RFC2404] from :
+ *
+ * Rm - Remote console random number
+ * SIDc - BMC session ID
+ * GUIDc - BMC guid
+ *
+ * generated by using SIK (the session integrity key). I am aware that the
+ * subscripts on the values look backwards, but that's the way they are
+ * written in the specification.
+ *
+ * If the authentication algorithm is IPMI_AUTH_RAKP_NONE, we return success.
+ *
+ * return 1 on success (the authcode matches)
+ * 0 on failure (the authcode does not match)
+ *
+ */
+int lanplus_rakp4_hmac_matches(const struct ipmi_session * session,
+ const uint8_t * bmc_mac,
+ struct ipmi_intf * intf)
+{
+ uint8_t * buffer;
+ int bufferLength, i;
+ uint8_t mac[EVP_MAX_MD_SIZE];
+ uint32_t macLength;
+ uint32_t cmpLength;
+ uint32_t SIDc_lsbf;
+ int unsupported = 0;
+ uint8_t alg;
+
+ if (ipmi_oem_active(intf, "intelplus")){
+ /* Intel BMC responds with the integrity Algorithm in RAKP4 */
+ if (session->v2_data.integrity_alg == IPMI_INTEGRITY_NONE)
+ return 1;
+
+ /* (Old) Intel BMC doesn't support other algorithms */
+ if ((session->v2_data.integrity_alg != IPMI_INTEGRITY_HMAC_SHA1_96) &&
+ (session->v2_data.integrity_alg != IPMI_INTEGRITY_HMAC_MD5_128)) {
+ printf("Error, unsupported rakp4 integrity_alg %d\n",
+ session->v2_data.integrity_alg);
+ return 1;
+ }
+ } else {
+ if (session->v2_data.auth_alg == IPMI_AUTH_RAKP_NONE)
+ return 1;
+
+ /* We don't yet support other algorithms (was assert) */
+ if ((session->v2_data.auth_alg != IPMI_AUTH_RAKP_HMAC_SHA1) &&
+ (session->v2_data.auth_alg != IPMI_AUTH_RAKP_HMAC_MD5) &&
+ (session->v2_data.auth_alg != IPMI_AUTH_RAKP_HMAC_SHA256)) {
+ printf("Error, unsupported rakp4 auth alg %d\n",
+ session->v2_data.auth_alg);
+ return 1;
+ }
+ }
+
+ bufferLength =
+ 16 + /* Rm */
+ 4 + /* SIDc */
+ 16; /* GUIDc */
+
+ buffer = (uint8_t *)malloc(bufferLength);
+ if (buffer == NULL) {
+ lprintf(LOG_ERR, "lanplus: malloc failure");
+ return 1;
+ }
+
+ /*
+ * Fill the buffer. I'm assuming that we're using the LSBF
+ * representation of the multibyte numbers in use.
+ */
+
+ /* Rm */
+ #if WORDS_BIGENDIAN
+ for (i = 0; i < 16; ++i)
+ buffer[i] = session->v2_data.console_rand[16 - 1 - i];
+ #else
+ for (i = 0; i < 16; ++i)
+ buffer[i] = session->v2_data.console_rand[i];
+ #endif
+
+
+ /* SIDc */
+ SIDc_lsbf = session->v2_data.bmc_id;
+ #if WORDS_BIGENDIAN
+ SIDc_lsbf = BSWAP_32(SIDc_lsbf);
+ #endif
+ memcpy(buffer + 16, &SIDc_lsbf, 4);
+
+
+ /* GUIDc */
+ #if WORDS_BIGENDIAN
+ for (i = 0; i < 16; ++i)
+ buffer[i + 20] = session->v2_data.bmc_guid[16 - 1 - i];
+ #else
+ for (i = 0; i < 16; ++i)
+ buffer[i + 20] = session->v2_data.bmc_guid[i];
+ #endif
+
+
+ if (verbose > 2)
+ {
+ printbuf((const uint8_t *)buffer, bufferLength, ">> rakp4 mac input buffer");
+ printbuf(session->v2_data.sik, session->v2_data.sik_len, ">> rakp4 mac key (sik)");
+ }
+
+
+ /*
+ * The buffer is complete. Let's hash.
+ */
+ alg = ( (ipmi_oem_active(intf, "intelplus"))
+ ? session->v2_data.integrity_alg
+ : session->v2_data.auth_alg );
+ lanplus_HMAC(alg,
+ session->v2_data.sik,
+ session->v2_data.sik_len,
+ buffer,
+ bufferLength,
+ mac,
+ &macLength);
+
+ if (verbose > 2)
+ {
+ printbuf(bmc_mac, macLength, ">> rakp4 mac as computed by the BMC");
+ printbuf(mac, macLength, ">> rakp4 mac as computed by the remote console");
+ }
+
+ if (ipmi_oem_active(intf, "intelplus")){
+ /* Intel BMC responds with the integrity Algorithm in RAKP4 */
+ switch(session->v2_data.integrity_alg)
+ {
+ case IPMI_INTEGRITY_HMAC_SHA1_96:
+ if (macLength != SHA_DIGEST_LENGTH) unsupported = 1;
+ cmpLength = IPMI_SHA1_AUTHCODE_SIZE;
+ break;
+ case IPMI_INTEGRITY_HMAC_MD5_128:
+ if (macLength != MD5_DIGEST_LENGTH) unsupported = 1;
+ cmpLength = IPMI_HMAC_MD5_AUTHCODE_SIZE;
+ break;
+ default:
+ unsupported = 1;
+ break;
+ }
+
+ } else {
+
+ /* We don't yet support other algorithms (was assert) */
+ switch(session->v2_data.auth_alg)
+ {
+ case IPMI_AUTH_RAKP_HMAC_SHA1:
+ if (macLength != SHA_DIGEST_LENGTH) unsupported = 1;
+ cmpLength = IPMI_SHA1_AUTHCODE_SIZE;
+ break;
+ case IPMI_AUTH_RAKP_HMAC_MD5 :
+ if (macLength != MD5_DIGEST_LENGTH) unsupported = 1;
+ cmpLength = IPMI_HMAC_MD5_AUTHCODE_SIZE;
+ break;
+ case IPMI_AUTH_RAKP_HMAC_SHA256:
+ if (macLength != SHA256_DIGEST_LENGTH) unsupported = 1;
+ cmpLength = IPMI_HMAC_SHA256_AUTHCODE_SIZE;
+ break;
+ default:
+ unsupported = 1;
+ break;
+ }
+ }
+ if (unsupported) {
+ printf("Unsupported rakp4 macLength %d for auth %d\n",
+ macLength, session->v2_data.auth_alg);
+ return 1;
+ }
+
+ free(buffer);
+ return (memcmp(bmc_mac, mac, cmpLength) == 0);
+}
+
+
+
+/*
+ * lanplus_generate_rakp3_auth_code
+ *
+ * This auth code is an HMAC generated with :
+ *
+ * Rc - BMC random number
+ * SIDm - Console session ID
+ * ROLEm - Requested privilege level (entire byte)
+ * ULENGTHm - Username length
+ * <USERNAME> - Usename (absent for null usernames)
+ *
+ * The key used to generated the MAC is Kuid
+ *
+ * I am aware that the subscripts look backwards, but that is the way they are
+ * written in the spec.
+ *
+ * param output_buffer [out] will hold the generated MAC
+ * param session [in] holds all the state data we need to generate the auth code
+ * param mac_length [out] will be set to the length of the auth code
+ *
+ * returns 0 on success
+ * 1 on failure
+ */
+int lanplus_generate_rakp3_authcode(uint8_t * output_buffer,
+ const struct ipmi_session * session,
+ uint32_t * mac_length,
+ struct ipmi_intf * intf)
+{
+ int ret = 0;
+ int input_buffer_length, i;
+ uint8_t * input_buffer;
+ uint32_t SIDm_lsbf;
+
+
+ if (session->v2_data.auth_alg == IPMI_AUTH_RAKP_NONE)
+ {
+ *mac_length = 0;
+ return 0;
+ }
+
+ /* We don't yet support other algorithms (was assert) */
+ if ((session->v2_data.auth_alg != IPMI_AUTH_RAKP_HMAC_SHA1) &&
+ (session->v2_data.auth_alg != IPMI_AUTH_RAKP_HMAC_MD5) &&
+ (session->v2_data.auth_alg != IPMI_AUTH_RAKP_HMAC_SHA256)) {
+ printf("Error, unsupported rakp3 auth alg %d\n",
+ session->v2_data.auth_alg);
+ return 1;
+ }
+
+ input_buffer_length =
+ 16 + /* Rc */
+ 4 + /* SIDm */
+ 1 + /* ROLEm */
+ 1 + /* ULENGTHm */
+ (int)strlen((const char *)session->username);
+
+ input_buffer = malloc(input_buffer_length);
+ if (input_buffer == NULL) {
+ lprintf(LOG_ERR, "lanplus: malloc failure");
+ return 1;
+ }
+
+ /*
+ * Fill the buffer. I'm assuming that we're using the LSBF representation of the
+ * multibyte numbers in use.
+ */
+
+ /* Rc */
+ #if WORDS_BIGENDIAN
+ for (i = 0; i < 16; ++i)
+ input_buffer[i] = session->v2_data.bmc_rand[16 - 1 - i];
+ #else
+ for (i = 0; i < 16; ++i)
+ input_buffer[i] = session->v2_data.bmc_rand[i];
+ #endif
+
+ /* SIDm */
+ SIDm_lsbf = session->v2_data.console_id;
+ #if WORDS_BIGENDIAN
+ SIDm_lsbf = BSWAP_32(SIDm_lsbf);
+ #endif
+ memcpy(input_buffer + 16, &SIDm_lsbf, 4);
+
+ /* ROLEm */
+ if (ipmi_oem_active(intf, "intelplus"))
+ input_buffer[20] = session->privlvl;
+ else
+ input_buffer[20] = session->v2_data.requested_role;
+
+ /* ULENGTHm */
+ input_buffer[21] = (uint8_t)strlen((const char *)session->username);
+
+ /* USERNAME */
+ for (i = 0; i < input_buffer[21]; ++i)
+ input_buffer[22 + i] = session->username[i];
+
+ if (verbose > 2)
+ {
+ printbuf((const uint8_t *)input_buffer, input_buffer_length, ">> rakp3 mac input buffer");
+ printbuf((const uint8_t *)session->authcode, IPMI_AUTHCODE_BUFFER_SIZE, ">> rakp3 mac key");
+ }
+
+ lanplus_HMAC(session->v2_data.auth_alg,
+ session->authcode,
+ IPMI_AUTHCODE_BUFFER_SIZE,
+ input_buffer,
+ input_buffer_length,
+ output_buffer,
+ mac_length);
+
+ if (verbose > 2)
+ printbuf((const uint8_t *)output_buffer, *mac_length, "generated rakp3 mac");
+
+
+ free(input_buffer);
+
+ return ret;
+}
+
+
+
+/*
+ * lanplus_generate_sik
+ *
+ * Generate the session integrity key (SIK) used for integrity checking
+ * during the IPMI v2 / RMCP+ session
+ *
+ * This session integrity key is a HMAC generated with :
+ *
+ * Rm - Console generated random number
+ * Rc - BMC generated random number
+ * ROLEm - Requested privilege level (entire byte)
+ * ULENGTHm - Username length
+ * <USERNAME> - Usename (absent for null usernames)
+ *
+ * The key used to generated the SIK is Kg if Kg is not null (two-key logins are
+ * enabled). Otherwise Kuid (the user authcode) is used as the key to genereate
+ * the SIK.
+ *
+ * I am aware that the subscripts look backwards, but that is the way they are
+ * written in the spec.
+ *
+ * param session [in/out] contains our input and output fields.
+ *
+ * returns 0 on success
+ * 1 on failure
+ */
+int lanplus_generate_sik(struct ipmi_session * session)
+{
+ uint8_t * input_buffer;
+ int input_buffer_length, i;
+ uint8_t * input_key;
+ uint32_t mac_length;
+ int unsupported = 0;
+
+ memset(session->v2_data.sik, 0, sizeof(session->v2_data.sik));
+ session->v2_data.sik_len = 0;
+
+ if (session->v2_data.auth_alg == IPMI_AUTH_RAKP_NONE)
+ return 0;
+
+ /* We don't yet support other algorithms (was assert) */
+ if ((session->v2_data.auth_alg != IPMI_AUTH_RAKP_HMAC_SHA1) &&
+ (session->v2_data.auth_alg != IPMI_AUTH_RAKP_HMAC_MD5) &&
+ (session->v2_data.auth_alg != IPMI_AUTH_RAKP_HMAC_SHA256)) {
+ printf("Error, unsupported sik auth alg %d\n",
+ session->v2_data.auth_alg);
+ return 1;
+ }
+
+ input_buffer_length =
+ 16 + /* Rm */
+ 16 + /* Rc */
+ 1 + /* ROLEm */
+ 1 + /* ULENGTHm */
+ (int)strlen((const char *)session->username);
+
+ input_buffer = malloc(input_buffer_length);
+ if (input_buffer == NULL) {
+ lprintf(LOG_ERR, "lanplus: malloc failure");
+ return 1;
+ }
+
+ /*
+ * Fill the buffer. I'm assuming that we're using the LSBF representation of the
+ * multibyte numbers in use.
+ */
+
+ /* Rm */
+ #if WORDS_BIGENDIAN
+ for (i = 0; i < 16; ++i)
+ input_buffer[i] = session->v2_data.console_rand[16 - 1 - i];
+ #else
+ for (i = 0; i < 16; ++i)
+ input_buffer[i] = session->v2_data.console_rand[i];
+ #endif
+
+
+ /* Rc */
+ #if WORDS_BIGENDIAN
+ for (i = 0; i < 16; ++i)
+ input_buffer[16 + i] = session->v2_data.bmc_rand[16 - 1 - i];
+ #else
+ for (i = 0; i < 16; ++i)
+ input_buffer[16 + i] = session->v2_data.bmc_rand[i];
+ #endif
+
+ /* ROLEm */
+ input_buffer[32] = session->v2_data.requested_role;
+
+ /* ULENGTHm */
+ input_buffer[33] = (uint8_t)strlen((const char *)session->username);
+
+ /* USERNAME */
+ for (i = 0; i < input_buffer[33]; ++i)
+ input_buffer[34 + i] = session->username[i];
+
+ if (session->v2_data.kg[0])
+ {
+ /* We will be hashing with Kg */
+ /*
+ * Section 13.31 of the IPMI v2 spec describes the SIK creation
+ * using Kg. It specifies that Kg should not be truncated.
+ * Kg is set in ipmi_intf.
+ */
+ input_key = session->v2_data.kg;
+ }
+ else
+ {
+ /* We will be hashing with Kuid */
+ input_key = session->authcode;
+ }
+
+
+ if (verbose >= 2)
+ printbuf((const uint8_t *)input_buffer, input_buffer_length, "session integrity key input");
+
+ lanplus_HMAC(session->v2_data.auth_alg,
+ input_key,
+ IPMI_AUTHCODE_BUFFER_SIZE,
+ input_buffer,
+ input_buffer_length,
+ session->v2_data.sik,
+ &mac_length);
+
+ free(input_buffer);
+ switch(session->v2_data.auth_alg)
+ {
+ case IPMI_AUTH_RAKP_HMAC_SHA1 :
+ if (mac_length != SHA_DIGEST_LENGTH) unsupported = 1; break;
+ case IPMI_AUTH_RAKP_HMAC_MD5 :
+ if (mac_length != MD5_DIGEST_LENGTH) unsupported = 1; break;
+ case IPMI_AUTH_RAKP_HMAC_SHA256:
+ if (mac_length != SHA256_DIGEST_LENGTH) unsupported = 1; break;
+ default : unsupported = 1; break;
+ }
+ if (unsupported) { /*was assert*/
+ printf("Unsupported sik macLength %d for auth %d\n",
+ mac_length, session->v2_data.auth_alg);
+ return 1;
+ }
+
+ session->v2_data.sik_len = (uint8_t)mac_length;
+
+ /*
+ * The key MAC generated is 20 bytes, but we will only be using the first
+ * 12 for SHA1 96
+ */
+ if (verbose >= 2)
+ printbuf(session->v2_data.sik, session->v2_data.sik_len, "Generated session integrity key");
+
+ return 0;
+}
+
+
+
+/*
+ * lanplus_generate_k1
+ *
+ * Generate K1, the key presumably used to generate integrity authcodes
+ *
+ * We use the authentication algorithm to generated the HMAC, using
+ * the session integrity key (SIK) as our key.
+ *
+ * param session [in/out].
+ *
+ * returns 0 on success
+ * 1 on failure
+ */
+int lanplus_generate_k1(struct ipmi_session * session)
+{
+ uint32_t mac_length;
+ int unsupported = 0;
+ uint8_t CONST_1[36] = /*EVP_MAX_MD_SIZE = 36*/
+ {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01};
+
+ if (session->v2_data.auth_alg == IPMI_AUTH_RAKP_NONE)
+ memcpy(session->v2_data.k1, CONST_1, 20);
+ else
+ {
+ lanplus_HMAC(session->v2_data.auth_alg,
+ session->v2_data.sik,
+ session->v2_data.sik_len,/* SIK length */
+ CONST_1,
+ IPMI_AUTHCODE_BUFFER_SIZE, /*=20*/
+ session->v2_data.k1,
+ &mac_length);
+ switch(session->v2_data.auth_alg)
+ {
+ case IPMI_AUTH_RAKP_HMAC_SHA1 :
+ if (mac_length != SHA_DIGEST_LENGTH) unsupported = 1; break;
+ case IPMI_AUTH_RAKP_HMAC_MD5 :
+ if (mac_length != MD5_DIGEST_LENGTH) unsupported = 1; break;
+ case IPMI_AUTH_RAKP_HMAC_SHA256:
+ if (mac_length != SHA256_DIGEST_LENGTH) unsupported = 1; break;
+ default : unsupported = 1; break;
+ }
+ if (unsupported) { /*was assert*/
+ printf("Unsupported k1 macLength %d for auth %d\n",
+ mac_length, session->v2_data.auth_alg);
+ return 1;
+ }
+ session->v2_data.k1_len = (uint8_t)mac_length;
+ }
+
+ if (verbose >= 2)
+ printbuf(session->v2_data.k1, session->v2_data.k1_len, "Generated K1");
+
+ return 0;
+}
+
+
+
+/*
+ * lanplus_generate_k2
+ *
+ * Generate K2, the key used for RMCP+ AES encryption.
+ *
+ * We use the authentication algorithm to generated the HMAC, using
+ * the session integrity key (SIK) as our key.
+ *
+ * param session [in/out].
+ *
+ * returns 0 on success
+ * 1 on failure
+ */
+int lanplus_generate_k2(struct ipmi_session * session)
+{
+ uint32_t mac_length;
+ int unsupported = 0;
+ uint8_t CONST_2[36] = /*EVP_MAX_MD_SIZE = 36*/
+ {0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02};
+
+ if (session->v2_data.auth_alg == IPMI_AUTH_RAKP_NONE)
+ memcpy(session->v2_data.k2, CONST_2, 20);
+ else
+ {
+ lanplus_HMAC(session->v2_data.auth_alg,
+ session->v2_data.sik,
+ session->v2_data.sik_len,/* SIK length */
+ CONST_2,
+ IPMI_AUTHCODE_BUFFER_SIZE, /*=20*/
+ session->v2_data.k2,
+ &mac_length);
+ switch(session->v2_data.auth_alg)
+ {
+ case IPMI_AUTH_RAKP_HMAC_SHA1 :
+ if (mac_length != SHA_DIGEST_LENGTH) unsupported = 1; break;
+ case IPMI_AUTH_RAKP_HMAC_MD5 :
+ if (mac_length != MD5_DIGEST_LENGTH) unsupported = 1; break;
+ case IPMI_AUTH_RAKP_HMAC_SHA256:
+ if (mac_length != SHA256_DIGEST_LENGTH) unsupported = 1; break;
+ default : unsupported = 1; break;
+ }
+ if (unsupported) { /*was assert*/
+ printf("Unsupported k2 macLength %d for auth %d\n",
+ mac_length, session->v2_data.auth_alg);
+ return 1;
+ }
+ session->v2_data.k2_len = (uint8_t)mac_length;
+ }
+
+ if (verbose >= 2)
+ printbuf(session->v2_data.k2, session->v2_data.k2_len, "Generated K2");
+
+ return 0;
+}
+
+
+
+/*
+ * lanplus_encrypt_payload
+ *
+ * Perform the appropriate encryption on the input data. Output the encrypted
+ * data to output, including the required confidentiality header and trailer.
+ * If the crypt_alg is IPMI_CRYPT_NONE, simply copy the input to the output and
+ * set bytes_written to input_length.
+ *
+ * param crypt_alg specifies the encryption algorithm (from table 13-19 of the
+ * IPMI v2 spec)
+ * param key is the used as input to the encryption algorithmf
+ * param input is the input data to be encrypted
+ * param input_length is the length of the input data to be encrypted
+ * param output is the cipher text generated by the encryption process
+ * param bytes_written is the number of bytes written during the encryption
+ * process
+ *
+ * returns 0 on success
+ * 1 on failure
+ */
+int lanplus_encrypt_payload(uint8_t crypt_alg,
+ const uint8_t * key,
+ const uint8_t * input,
+ uint32_t input_length,
+ uint8_t * output,
+ uint16_t * bytes_written)
+{
+ uint8_t * padded_input;
+ uint32_t mod, i, bytes_encrypted;
+ uint8_t pad_length = 0;
+
+ if (crypt_alg == IPMI_CRYPT_NONE)
+ {
+ /* Just copy the input to the output */
+ *bytes_written = (uint16_t)input_length;
+ return 0;
+ }
+
+ /* Currently, we only support AES (was assert) */
+ if ((crypt_alg != IPMI_CRYPT_AES_CBC_128) ||
+ (input_length > IPMI_MAX_PAYLOAD_SIZE)) {
+ lprintf(LOG_ERR,"lanplus crypt: unsupported alg %d or len %d\n",
+ crypt_alg,input_length);
+ return 1;
+ }
+
+ /*
+ * The input to the AES encryption algorithm has to be a multiple of the
+ * block size (16 bytes). The extra byte we are adding is the pad length
+ * byte.
+ */
+ mod = (input_length + 1) % IPMI_CRYPT_AES_CBC_128_BLOCK_SIZE;
+ if (mod)
+ pad_length = IPMI_CRYPT_AES_CBC_128_BLOCK_SIZE - mod;
+
+ padded_input = (uint8_t*)malloc(input_length + pad_length + 1);
+ if (padded_input == NULL) {
+ lprintf(LOG_ERR, "lanplus: malloc failure");
+ return 1;
+ }
+ memcpy(padded_input, input, input_length);
+
+ /* add the pad */
+ for (i = 0; i < pad_length; ++i)
+ padded_input[input_length + i] = i + 1;
+
+ /* add the pad length */
+ padded_input[input_length + pad_length] = pad_length;
+
+ /* Generate an initialization vector, IV, for the encryption process */
+ if (lanplus_rand(output, IPMI_CRYPT_AES_CBC_128_BLOCK_SIZE))
+ {
+ lprintf(LOG_ERR, "lanplus_encrypt_payload: Error generating IV");
+ free(padded_input);
+ return 1;
+ }
+
+ if (verbose > 2)
+ printbuf(output, IPMI_CRYPT_AES_CBC_128_BLOCK_SIZE, ">> Initialization vector");
+
+
+
+ lanplus_encrypt_aes_cbc_128(output, /* IV */
+ key, /* K2 */
+ padded_input, /* Data to encrypt */
+ input_length + pad_length + 1, /* Input length */
+ output + IPMI_CRYPT_AES_CBC_128_BLOCK_SIZE, /* output */
+ &bytes_encrypted); /* bytes written */
+
+ *bytes_written =
+ IPMI_CRYPT_AES_CBC_128_BLOCK_SIZE + /* IV */
+ bytes_encrypted;
+
+ free(padded_input);
+
+ return 0;
+}
+
+
+
+/*
+ * lanplus_has_valid_auth_code
+ *
+ * Determine whether the packets authcode field is valid for packet.
+ *
+ * We always return success if any of the following are true.
+ * - this is not an IPMIv2 packet
+ * - the session is not yet active
+ * - the packet specifies that it is not authenticated
+ * - the integrity algorithm agreed upon during session creation is "none"
+ *
+ * The authcode is computed using the specified integrity algorithm starting
+ * with the AuthType / Format field, and ending with the field immediately
+ * preceeding the authcode itself.
+ *
+ * The key key used to generate the authcode MAC is K1.
+ *
+ * param rs holds the response structure.
+ * param session holds our session state, including our chosen algorithm, key, etc.
+ *
+ * returns 1 on success (authcode is valid)
+ * 0 on failure (autchode integrity check failed)
+ */
+int lanplus_has_valid_auth_code(struct ipmi_rs * rs,
+ struct ipmi_session * session)
+{
+ uint8_t * bmc_authcode;
+ uint8_t generated_authcode[EVP_MAX_MD_SIZE];
+ uint32_t generated_authcode_length;
+ uint32_t authcode_length;
+
+
+ if ((rs->session.authtype != IPMI_SESSION_AUTHTYPE_RMCP_PLUS) ||
+ (session->v2_data.session_state != LANPLUS_STATE_ACTIVE) ||
+ (! rs->session.bAuthenticated) ||
+ (session->v2_data.integrity_alg == IPMI_INTEGRITY_NONE))
+ return 1;
+
+ switch(session->v2_data.integrity_alg)
+ {
+ case IPMI_INTEGRITY_HMAC_SHA1_96 : authcode_length = IPMI_SHA1_AUTHCODE_SIZE; break;
+ case IPMI_INTEGRITY_HMAC_MD5_128 : authcode_length = IPMI_HMAC_MD5_AUTHCODE_SIZE; break;
+ case IPMI_INTEGRITY_HMAC_SHA256_128: authcode_length = IPMI_HMAC_SHA256_AUTHCODE_SIZE; break;
+ /* Unsupported */
+ default: printf("Unsupported lanplus auth_code %d\n",
+ session->v2_data.auth_alg);
+ return 1; break;
+ }
+
+ /*
+ * For SHA1-96, the authcode will be the last 12 bytes in the packet
+ */
+ bmc_authcode = rs->data + (rs->data_len - authcode_length);
+
+ lanplus_HMAC(session->v2_data.integrity_alg,
+ session->v2_data.k1,
+ session->v2_data.k1_len,
+ rs->data + IPMI_LANPLUS_OFFSET_AUTHTYPE,
+ rs->data_len - IPMI_LANPLUS_OFFSET_AUTHTYPE - authcode_length,
+ generated_authcode,
+ &generated_authcode_length);
+
+ if (verbose > 3)
+ {
+ lprintf(LOG_DEBUG+2, "Validating authcode");
+ printbuf(session->v2_data.k1, session->v2_data.k1_len, "K1");
+ printbuf(rs->data + IPMI_LANPLUS_OFFSET_AUTHTYPE,
+ rs->data_len - IPMI_LANPLUS_OFFSET_AUTHTYPE - authcode_length,
+ "Authcode Input Data");
+ printbuf(generated_authcode, authcode_length, "Generated authcode");
+ printbuf(bmc_authcode, authcode_length, "Expected authcode");
+ }
+
+// assert(generated_authcode_length == 20);
+ return (memcmp(bmc_authcode, generated_authcode, authcode_length) == 0);
+}
+
+
+
+/*
+ * lanplus_decrypt_payload
+ *
+ *
+ * param input points to the beginning of the payload (which will be the IV if
+ * we are using AES)
+ * param payload_size [out] will be set to the size of the payload EXCLUDING
+ * padding
+ *
+ * returns 0 on success (we were able to successfully decrypt the packet)
+ * 1 on failure (we were unable to successfully decrypt the packet)
+ */
+int lanplus_decrypt_payload(uint8_t crypt_alg,
+ const uint8_t * key,
+ const uint8_t * input,
+ uint32_t input_length,
+ uint8_t * output,
+ uint16_t * payload_size)
+{
+ uint8_t * decrypted_payload;
+ uint32_t bytes_decrypted;
+
+ if (crypt_alg == IPMI_CRYPT_NONE)
+ {
+ /* We are not encrypted. The paylaod size is is everything. */
+ *payload_size = (uint16_t)input_length;
+ memmove(output, input, input_length);
+ return 0;
+ }
+
+ /* We only support AES (was assert) */
+ if (crypt_alg != IPMI_CRYPT_AES_CBC_128) {
+ lprintf(LOG_ERR,"lanplus decrypt: unsupported alg %d\n",
+ crypt_alg);
+ return 1;
+ }
+
+ decrypted_payload = (uint8_t*)malloc(input_length);
+ if (decrypted_payload == NULL) {
+ lprintf(LOG_ERR, "lanplus: malloc failure");
+ return 1;
+ }
+
+ lanplus_decrypt_aes_cbc_128(input, /* IV */
+ key, /* Key */
+ input + /* Data to decrypt */
+ IPMI_CRYPT_AES_CBC_128_BLOCK_SIZE,
+ input_length - /* Input length */
+ IPMI_CRYPT_AES_CBC_128_BLOCK_SIZE,
+ decrypted_payload, /* output */
+ &bytes_decrypted); /* bytes written */
+
+ if (bytes_decrypted != 0)
+ {
+ /* Success */
+ uint8_t conf_pad_length;
+ int i;
+
+ memmove(output,
+ decrypted_payload,
+ bytes_decrypted);
+
+ /*
+ * We have to determine the payload size, by substracting the padding, etc.
+ * The last byte of the decrypted payload is the confidentiality pad length.
+ */
+ conf_pad_length = decrypted_payload[bytes_decrypted - 1];
+ *payload_size = bytes_decrypted - conf_pad_length - 1;
+
+ /*
+ * Extra test to make sure that the padding looks like it should (should start
+ * with 0x01, 0x02, 0x03, etc...
+ */
+ for (i = 0; i < conf_pad_length; ++i)
+ {
+ if (decrypted_payload[*payload_size + i] == i)
+ {
+ lprintf(LOG_ERR, "Malformed payload padding");
+ return 1; /* assert(0); */
+ }
+ }
+ }
+ else
+ {
+ lprintf(LOG_ERR, "ERROR: lanplus_decrypt_aes_cbc_128 decryptd 0 bytes");
+ return 1; /* assert(0); */
+ }
+
+ free(decrypted_payload);
+ return (bytes_decrypted == 0);
+}
diff --git a/lib/lanplus/lanplus_crypt.h b/lib/lanplus/lanplus_crypt.h
new file mode 100644
index 0000000..2756bdd
--- /dev/null
+++ b/lib/lanplus/lanplus_crypt.h
@@ -0,0 +1,79 @@
+/*
+ * 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.
+ */
+
+#ifndef IPMI_LANPLUS_CRYPT_H
+#define IPMI_LANPLUS_CRYPT_H
+
+#include <ipmitool/ipmi_intf.h>
+
+#include <openssl/evp.h>
+#include <openssl/sha.h>
+#include <openssl/md5.h>
+
+/*
+ * See the implementation file for documentation
+ * ipmi_intf can be used for oem specific implementations
+ * e.g. if (ipmi_oem_active(intf, "OEM_XYZ"))
+ */
+
+int lanplus_rakp2_hmac_matches(const struct ipmi_session * session,
+ const uint8_t * hmac,
+ struct ipmi_intf * intf);
+int lanplus_rakp4_hmac_matches(const struct ipmi_session * session,
+ const uint8_t * hmac,
+ struct ipmi_intf * intf);
+int lanplus_generate_rakp3_authcode(uint8_t * buffer,
+ const struct ipmi_session * session,
+ uint32_t * auth_length,
+ struct ipmi_intf * intf);
+int lanplus_generate_sik(struct ipmi_session * session);
+int lanplus_generate_k1(struct ipmi_session * session);
+int lanplus_generate_k2(struct ipmi_session * session);
+int lanplus_encrypt_payload(uint8_t crypt_alg,
+ const uint8_t * key,
+ const uint8_t * input,
+ uint32_t input_length,
+ uint8_t * output,
+ uint16_t * bytesWritten);
+int lanplus_decrypt_payload(uint8_t crypt_alg,
+ const uint8_t * key,
+ const uint8_t * input,
+ uint32_t input_length,
+ uint8_t * output,
+ uint16_t * payload_size);
+int lanplus_has_valid_auth_code(struct ipmi_rs * rs,
+ struct ipmi_session * session);
+
+
+
+
+#endif /* IPMI_LANPLUS_CRYPT_H */
diff --git a/lib/lanplus/lanplus_crypt_impl.c b/lib/lanplus/lanplus_crypt_impl.c
new file mode 100644
index 0000000..3f9679e
--- /dev/null
+++ b/lib/lanplus/lanplus_crypt_impl.c
@@ -0,0 +1,320 @@
+/*
+ * 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.
+ */
+/* ARCress, TODO: improve error handling and remove all assert() calls here. */
+
+#include "ipmitool/log.h"
+#include "ipmitool/ipmi_constants.h"
+#include "lanplus.h"
+#include "lanplus_crypt_impl.h"
+#include <openssl/hmac.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#include <openssl/err.h>
+#include <assert.h>
+
+
+
+/*
+ * lanplus_seed_prng
+ *
+ * Seed our PRNG with the specified number of bytes from /dev/random
+ *
+ * param bytes specifies the number of bytes to read from /dev/random
+ *
+ * returns 0 on success
+ * 1 on failure
+ */
+int lanplus_seed_prng(uint32_t bytes)
+{
+#ifdef WIN32
+ const char *randfile;
+ char buffer[200];
+ static FILE *fp = NULL;
+ size_t i;
+ randfile = RAND_file_name(buffer, sizeof buffer); /* usu C:\.rnd */
+ if ((randfile != NULL) && (fp == NULL)) {
+ /*first time, so open/create file*/
+ fp = fopen(randfile,"w"); /*create the randfile*/
+ if (fp != NULL) {
+ i = fwrite(" \n",2,1,fp);
+ fclose(fp);
+ }
+ }
+ if (verbose > 0)
+ printf("seed_prng: RAND_file_name = %s, fp=%p\n",randfile,fp);
+#else
+ const char *randfile = "/dev/urandom";
+#endif
+
+ if (RAND_load_file(randfile, bytes) == 0) {
+ printf("seed_prng: RAND_load_file(%s) failed\n",randfile);
+ return 1;
+ } else { /*success*/
+ return 0;
+ }
+}
+
+/*
+ * lanplus_rand
+ *
+ * Generate a random number of the specified size
+ *
+ * param num_bytes [in] is the size of the random number to be
+ * generated
+ * param buffer [out] is where we will place our random number
+ *
+ * return 0 on success
+ * 1 on failure
+ */
+int
+lanplus_rand(uint8_t * buffer, uint32_t num_bytes)
+{
+#undef IPMI_LANPLUS_FAKE_RAND
+#ifdef IPMI_LANPLUS_FAKE_RAND
+ /*
+ * This code exists so that we can easily find the generated random
+ * number in the hex dumps.
+ */
+ int i;
+ for (i = 0; i < num_bytes; ++i)
+ buffer[i] = 0x70 | i;
+ return 0;
+#else
+ return (! RAND_bytes(buffer, num_bytes));
+#endif
+}
+
+/*
+ * lanplus_HMAC
+ *
+ * param mac specifies the algorithm to be used, currently only SHA1 is supported
+ * param key is the key used for HMAC generation
+ * param key_len is the lenght of key
+ * param d is the data to be MAC'd
+ * param n is the length of the data at d
+ * param md is the result of the HMAC algorithm
+ * param md_len is the length of md
+ *
+ * returns a pointer to md
+ */
+uint8_t *
+lanplus_HMAC(uint8_t mac,
+ const void *key,
+ int key_len,
+ const uint8_t *d,
+ int n,
+ uint8_t *md,
+ uint32_t *md_len)
+{
+ const EVP_MD *evp_md = NULL;
+ unsigned int mlen;
+ uint8_t *pnew;
+
+ *md_len = 0; /*if return NULL, also return zero length*/
+ if ((mac == IPMI_AUTH_RAKP_HMAC_SHA1) ||
+ (mac == IPMI_INTEGRITY_HMAC_SHA1_96))
+ evp_md = EVP_sha1();
+ else if ((mac == IPMI_AUTH_RAKP_HMAC_MD5) ||
+ (mac == IPMI_INTEGRITY_HMAC_MD5_128))
+ evp_md = EVP_md5();
+ else if ((mac == IPMI_AUTH_RAKP_HMAC_SHA256) ||
+ (mac == IPMI_INTEGRITY_HMAC_SHA256_128)) {
+#ifdef HAVE_SHA256
+ evp_md = EVP_sha256();
+#else
+ lprintf(LOG_ERR, "Invalid EVP_sha256 in lanplus_HMAC");
+ return NULL; // assert(0);
+#endif
+ } else {
+ lprintf(LOG_ERR,"Invalid mac type 0x%x in lanplus_HMAC",mac);
+ return NULL; // assert(0);
+ }
+ mlen = 20; /* *md_len is usually not initialized */
+ pnew = HMAC(evp_md, key, key_len, d, n, md, &mlen);
+ *md_len = (uint32_t)mlen;
+ return(pnew);
+}
+
+
+/*
+ * lanplus_encrypt_aes_cbc_128
+ *
+ * Encrypt with the AES CBC 128 algorithm
+ *
+ * param iv is the 16 byte initialization vector
+ * param key is the 16 byte key used by the AES algorithm
+ * param input is the data to be encrypted
+ * param input_length is the number of bytes to be encrypted. This MUST
+ * be a multiple of the block size, 16.
+ * param output is the encrypted output
+ * param bytes_written is the number of bytes written. This param is set
+ * to 0 on failure, or if 0 bytes were input.
+ */
+void
+lanplus_encrypt_aes_cbc_128(const uint8_t * iv,
+ const uint8_t * key,
+ const uint8_t * input,
+ uint32_t input_length,
+ uint8_t * output,
+ uint32_t * bytes_written)
+{
+ int nwritten = 0;
+ int inlen = 0;
+ EVP_CIPHER_CTX ctx;
+ EVP_CIPHER_CTX_init(&ctx);
+ EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key, iv);
+ EVP_CIPHER_CTX_set_padding(&ctx, 0);
+
+ *bytes_written = 0;
+ if (input_length == 0) return;
+
+ if (verbose >= 5)
+ {
+ printbuf(iv, 16, "encrypting with this IV");
+ printbuf(key, 16, "encrypting with this key");
+ printbuf(input, input_length, "encrypting this data");
+ }
+
+ /*
+ * The default implementation adds a whole block of padding if the input
+ * data is perfectly aligned. We would like to keep that from happening.
+ * We have made a point to have our input perfectly padded.
+ */
+ assert((input_length % IPMI_CRYPT_AES_CBC_128_BLOCK_SIZE) == 0);
+ inlen = input_length;
+
+ if(!EVP_EncryptUpdate(&ctx, output, &nwritten, input, inlen))
+ {
+ /* Error */
+ *bytes_written = 0;
+ return;
+ }
+ else
+ {
+ int tmplen;
+
+ if(!EVP_EncryptFinal_ex(&ctx, output + nwritten, &tmplen))
+ {
+ *bytes_written = 0;
+ return; /* Error */
+ }
+ else
+ {
+ /* Success */
+ *bytes_written = nwritten + tmplen;
+ EVP_CIPHER_CTX_cleanup(&ctx);
+ }
+ }
+}
+
+
+/*
+ * lanplus_decrypt_aes_cbc_128
+ *
+ * Decrypt with the AES CBC 128 algorithm
+ *
+ * param iv is the 16 byte initialization vector
+ * param key is the 16 byte key used by the AES algorithm
+ * param input is the data to be decrypted
+ * param input_length is the number of bytes to be decrypted. This MUST
+ * be a multiple of the block size, 16.
+ * param output is the decrypted output
+ * param bytes_written is the number of bytes written. This param is set
+ * to 0 on failure, or if 0 bytes were input.
+ */
+void
+lanplus_decrypt_aes_cbc_128(const uint8_t * iv,
+ const uint8_t * key,
+ const uint8_t * input,
+ uint32_t input_length,
+ uint8_t * output,
+ uint32_t * bytes_written)
+{
+ int nwritten = 0;
+ int inlen = 0;
+ EVP_CIPHER_CTX ctx;
+ EVP_CIPHER_CTX_init(&ctx);
+ EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key, iv);
+ EVP_CIPHER_CTX_set_padding(&ctx, 0);
+
+ if (verbose >= 5)
+ {
+ printbuf(iv, 16, "decrypting with this IV");
+ printbuf(key, 16, "decrypting with this key");
+ printbuf(input, input_length, "decrypting this data");
+ }
+
+ *bytes_written = 0;
+ if (input_length == 0) return;
+
+ /*
+ * The default implementation adds a whole block of padding if the input
+ * data is perfectly aligned. We would like to keep that from happening.
+ * We have made a point to have our input perfectly padded.
+ */
+ assert((input_length % IPMI_CRYPT_AES_CBC_128_BLOCK_SIZE) == 0);
+ inlen = input_length;
+
+ if (!EVP_DecryptUpdate(&ctx, output, &nwritten, input, inlen))
+ {
+ /* Error */
+ lprintf(LOG_DEBUG, "ERROR: decrypt update failed");
+ *bytes_written = 0;
+ return;
+ }
+ else
+ {
+ int tmplen;
+
+ if (!EVP_DecryptFinal_ex(&ctx, output + nwritten, &tmplen))
+ {
+ char buffer[1000];
+ ERR_error_string(ERR_get_error(), buffer);
+ lprintf(LOG_DEBUG, "the ERR error %s", buffer);
+ lprintf(LOG_DEBUG, "ERROR: decrypt final failed");
+ *bytes_written = 0;
+ return; /* Error */
+ }
+ else
+ {
+ /* Success */
+ *bytes_written = nwritten + tmplen;
+ EVP_CIPHER_CTX_cleanup(&ctx);
+ }
+ }
+
+ if (verbose >= 5)
+ {
+ lprintf(LOG_DEBUG, "Decrypted %d encrypted bytes",input_length);
+ printbuf(output, *bytes_written, "Decrypted this data");
+ }
+}
diff --git a/lib/lanplus/lanplus_crypt_impl.h b/lib/lanplus/lanplus_crypt_impl.h
new file mode 100644
index 0000000..ff534bc
--- /dev/null
+++ b/lib/lanplus/lanplus_crypt_impl.h
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ */
+
+#ifndef IPMI_LANPLUS_CRYPT_IMPL_H
+#define IPMI_LANPLUS_CRYPT_IMPL_H
+
+
+int
+lanplus_seed_prng(uint32_t bytes);
+
+int
+lanplus_rand(uint8_t * buffer, uint32_t num_bytes);
+
+uint8_t *
+lanplus_HMAC(uint8_t mac, const void *key, int key_len,
+ const uint8_t *d, int n, uint8_t *md,
+ uint32_t *md_len);
+
+void
+lanplus_encrypt_aes_cbc_128(const uint8_t * iv,
+ const uint8_t * key,
+ const uint8_t * input,
+ uint32_t input_length,
+ uint8_t * output,
+ uint32_t * bytes_written);
+
+
+void
+lanplus_decrypt_aes_cbc_128(const uint8_t * iv,
+ const uint8_t * key,
+ const uint8_t * input,
+ uint32_t input_length,
+ uint8_t * output,
+ uint32_t * bytes_written);
+
+
+#endif /* IPMI_LANPLUS_CRYPT_IMPL_H */
diff --git a/lib/lanplus/lanplus_defs.h b/lib/lanplus/lanplus_defs.h
new file mode 100644
index 0000000..dbce90d
--- /dev/null
+++ b/lib/lanplus/lanplus_defs.h
@@ -0,0 +1,376 @@
+/*
+ * lanplus_defs.h: (extracted from ipmitool/ipmi_intf.h)
+ *
+ * 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.
+ */
+
+#ifndef LANPLUS_DEFS_H
+#define LANPLUS_DEFS_H
+
+#if defined(HAVE_CONFIG_H)
+#include "config.h"
+#else
+#ifndef socklen_t
+typedef unsigned int socklen_t;
+#endif
+#endif
+
+
+#if defined(MACOS)
+#include <stdint.h>
+#endif
+
+#include <openssl/evp.h>
+
+#ifdef WIN32
+#define SockType SOCKET
+#define SockInvalid INVALID_SOCKET /*=0*/
+#else
+#define SockType int
+#define SockInvalid -1
+#endif
+
+#ifndef IPMI_H
+
+#ifndef _IPMI_RQ_
+#define _IPMI_RQ_
+struct ipmi_rq {
+ struct {
+ uint8_t netfn:6;
+ uint8_t lun:2;
+ uint8_t cmd;
+ uint8_t target_cmd;
+ uint16_t data_len;
+ uint8_t *data;
+ } msg;
+};
+#endif
+
+#ifndef _IPMI_RS_
+#define _IPMI_RS_
+struct ipmi_rs {
+ uint8_t ccode;
+ uint8_t data[IPMI_BUF_SIZE];
+
+ /*
+ * Looks like this is the length of the entire packet, including the RMCP
+ * stuff, then modified to be the length of the extra IPMI message data
+ */
+ int data_len;
+
+ struct {
+ uint8_t netfn;
+ uint8_t cmd;
+ uint8_t seq;
+ uint8_t lun;
+ } msg;
+
+ struct {
+ uint8_t authtype;
+ uint32_t seq;
+ uint32_t id;
+ uint8_t bEncrypted; /* IPMI v2 only */
+ uint8_t bAuthenticated; /* IPMI v2 only */
+ uint8_t payloadtype; /* IPMI v2 only */
+ /* This is the total length of the payload or
+ IPMI message. IPMI v2.0 requires this to
+ be 2 bytes. Not really used for much. */
+ uint16_t msglen;
+ } session;
+
+ /*
+ * A union of the different possible payload meta-data
+ */
+ union {
+ struct {
+ uint8_t rq_addr;
+ uint8_t netfn;
+ uint8_t rq_lun;
+ uint8_t rs_addr;
+ uint8_t rq_seq;
+ uint8_t rs_lun;
+ uint8_t cmd;
+ } ipmi_response;
+ struct {
+ uint8_t message_tag;
+ uint8_t rakp_return_code;
+ uint8_t max_priv_level;
+ uint32_t console_id;
+ uint32_t bmc_id;
+ uint8_t auth_alg;
+ uint8_t integrity_alg;
+ uint8_t crypt_alg;
+ } open_session_response;
+ struct {
+ uint8_t message_tag;
+ uint8_t rakp_return_code;
+ uint32_t console_id;
+ uint8_t bmc_rand[16]; /* Random number generated by the BMC */
+ uint8_t bmc_guid[16];
+ uint8_t key_exchange_auth_code[EVP_MAX_MD_SIZE];
+ } rakp2_message;
+ struct {
+ uint8_t message_tag;
+ uint8_t rakp_return_code;
+ uint32_t console_id;
+ uint8_t integrity_check_value[EVP_MAX_MD_SIZE];
+ } rakp4_message;
+ struct {
+ uint8_t packet_sequence_number;
+ uint8_t acked_packet_number;
+ uint8_t accepted_character_count;
+ uint8_t is_nack; /* bool */
+ uint8_t transfer_unavailable; /* bool */
+ uint8_t sol_inactive; /* bool */
+ uint8_t transmit_overrun; /* bool */
+ uint8_t break_detected; /* bool */
+ } sol_packet;
+
+ } payload;
+};
+#endif
+
+struct ipmi_v2_payload {
+ uint16_t payload_length;
+ uint8_t payload_type;
+
+ union {
+
+ struct {
+ uint8_t rq_seq;
+ struct ipmi_rq *request;
+ } ipmi_request;
+
+ struct {
+ uint8_t rs_seq;
+ struct ipmi_rs *response;
+ } ipmi_response;
+
+ /* Only used internally by the lanplus interface */
+ struct {
+ uint8_t *request;
+ } open_session_request;
+
+ /* Only used internally by the lanplus interface */
+ struct {
+ uint8_t *message;
+ } rakp_1_message;
+
+ /* Only used internally by the lanplus interface */
+ struct {
+ uint8_t *message;
+ } rakp_2_message;
+
+ /* Only used internally by the lanplus interface */
+ struct {
+ uint8_t *message;
+ } rakp_3_message;
+
+ /* Only used internally by the lanplus interface */
+ struct {
+ uint8_t *message;
+ } rakp_4_message;
+
+ struct {
+ uint8_t data[IPMI_BUF_SIZE];
+ uint16_t character_count;
+ uint8_t packet_sequence_number;
+ uint8_t acked_packet_number;
+ uint8_t accepted_character_count;
+ uint8_t is_nack; /* bool */
+ uint8_t assert_ring_wor; /* bool */
+ uint8_t generate_break; /* bool */
+ uint8_t deassert_cts; /* bool */
+ uint8_t deassert_dcd_dsr; /* bool */
+ uint8_t flush_inbound; /* bool */
+ uint8_t flush_outbound; /* bool */
+ } sol_packet;
+
+ } payload;
+};
+#endif
+/**************************************/
+
+/* define ipmi_intf locally */
+/*
+ * An enumeration that describes every possible session state for
+ * an IPMIv2 / RMCP+ session.
+ */
+enum LANPLUS_SESSION_STATE {
+ LANPLUS_STATE_PRESESSION = 0,
+ LANPLUS_STATE_OPEN_SESSION_SENT,
+ LANPLUS_STATE_OPEN_SESSION_RECEIEVED,
+ LANPLUS_STATE_RAKP_1_SENT,
+ LANPLUS_STATE_RAKP_2_RECEIVED,
+ LANPLUS_STATE_RAKP_3_SENT,
+ LANPLUS_STATE_ACTIVE,
+ LANPLUS_STATE_CLOSE_SENT,
+};
+
+
+#define IPMI_AUTHCODE_BUFFER_SIZE 20 // KG or KUID
+#define IPMI_SIK_BUFFER_SIZE EVP_MAX_MD_SIZE
+#define IPMI_KG_BUFFER_SIZE 21 /* key plus null byte */
+
+struct ipmi_session {
+ uint8_t hostname[64];
+ uint8_t username[17];
+ uint8_t authcode[IPMI_AUTHCODE_BUFFER_SIZE + 1];
+ uint8_t challenge[16];
+ uint8_t authtype;
+ uint8_t authtype_set;
+#define IPMI_AUTHSTATUS_PER_MSG_DISABLED 0x10
+#define IPMI_AUTHSTATUS_PER_USER_DISABLED 0x08
+#define IPMI_AUTHSTATUS_NONNULL_USERS_ENABLED 0x04
+#define IPMI_AUTHSTATUS_NULL_USERS_ENABLED 0x02
+#define IPMI_AUTHSTATUS_ANONYMOUS_USERS_ENABLED 0x01
+ uint8_t authstatus;
+ uint8_t authextra;
+ uint8_t privlvl;
+ uint8_t cipher_suite_id;
+ char sol_escape_char;
+ int password;
+ int port;
+ int active;
+ int retry;
+
+ uint32_t session_id;
+ uint32_t in_seq;
+ uint32_t out_seq;
+ uint32_t timeout;
+
+#ifdef HAVE_IPV6
+ /* struct sockaddr_storage addr; *causes rest of structure to break */
+ struct sockaddr_in addr;
+#else
+ struct sockaddr_in addr;
+#endif
+ socklen_t addrlen;
+
+ /*
+ * This struct holds state data specific to IMPI v2 / RMCP+ sessions
+ */
+ struct {
+ enum LANPLUS_SESSION_STATE session_state;
+
+ /* These are the algorithms agreed upon for the session */
+ uint8_t requested_auth_alg;
+ uint8_t requested_integrity_alg;
+ uint8_t requested_crypt_alg;
+ uint8_t auth_alg;
+ uint8_t integrity_alg;
+ uint8_t crypt_alg;
+ uint8_t max_priv_level;
+
+ uint32_t console_id;
+ uint32_t bmc_id;
+
+ /*
+ * Values required for RAKP mesages
+ */
+
+ /* Random number generated byt the console */
+ uint8_t console_rand[16];
+ /* Random number generated by the BMC */
+ uint8_t bmc_rand[16];
+
+ uint8_t bmc_guid[16];
+ uint8_t requested_role; /* As sent in the RAKP 1 message */
+ uint8_t rakp2_return_code;
+
+ uint8_t sik[EVP_MAX_MD_SIZE]; /* Session integrity key */
+ uint8_t kg[IPMI_KG_BUFFER_SIZE]; /* BMC key */
+ uint8_t k1[EVP_MAX_MD_SIZE]; /* Used for Integrity checking? */
+ uint8_t k2[EVP_MAX_MD_SIZE]; /* First 16 bytes used for AES */
+ uint8_t sik_len; /* length of sik */
+ uint8_t k1_len; /* length of k1 */
+ uint8_t k2_len; /* length of k2 */
+ } v2_data;
+
+
+ /*
+ * This data is specific to the Serial Over Lan session
+ */
+ struct {
+ uint16_t max_inbound_payload_size;
+ uint16_t max_outbound_payload_size;
+ uint16_t port;
+ uint8_t sequence_number;
+
+ /* This data describes the last SOL packet */
+ uint8_t last_received_sequence_number;
+ uint8_t last_received_byte_count;
+ void (*sol_input_handler)(struct ipmi_rs * rsp);
+ } sol_data;
+};
+
+struct ipmi_intf_support {
+ const char * name;
+ int supported;
+};
+
+struct ipmi_intf {
+ char name[16];
+ char desc[128];
+ SockType fd;
+ int opened;
+ int abort;
+ int noanswer;
+
+ struct ipmi_session * session;
+ struct ipmi_oem_handle * oem;
+ struct ipmi_cmd * cmdlist;
+ uint32_t my_addr;
+ uint32_t target_addr;
+ uint8_t target_lun;
+ uint8_t target_channel;
+ uint32_t transit_addr;
+ uint8_t transit_channel;
+ uint8_t devnum;
+
+ int (*setup)(struct ipmi_intf * intf);
+ int (*open)(struct ipmi_intf * intf);
+ void (*close)(struct ipmi_intf * intf);
+ struct ipmi_rs *(*sendrecv)(struct ipmi_intf * intf, struct ipmi_rq * req);
+ int (*sendrsp)(struct ipmi_intf * intf, struct ipmi_rs * rsp);
+ struct ipmi_rs *(*recv_sol)(struct ipmi_intf * intf);
+ struct ipmi_rs *(*send_sol)(struct ipmi_intf * intf, void *payload);
+ /*struct ipmi_v2_payload * payload);*/
+ int (*keepalive)(struct ipmi_intf * intf);
+};
+
+struct ipmi_cmd {
+ int (*func)(struct ipmi_intf * intf, int argc, char ** argv);
+ const char * name;
+ const char * desc;
+};
+
+#endif /* lanplus_defs.h */
diff --git a/lib/lanplus/lanplus_dump.c b/lib/lanplus/lanplus_dump.c
new file mode 100644
index 0000000..5c86b69
--- /dev/null
+++ b/lib/lanplus/lanplus_dump.c
@@ -0,0 +1,174 @@
+/*
+ * 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.
+ */
+
+#include "lanplus.h"
+#include "lanplus_crypt.h"
+#include "lanplus_dump.h"
+
+extern const struct valstr ipmi_rakp_return_codes[];
+extern const struct valstr ipmi_priv_levels[];
+extern const struct valstr ipmi_auth_algorithms[];
+extern const struct valstr ipmi_integrity_algorithms[];
+extern const struct valstr ipmi_encryption_algorithms[];
+
+#define DUMP_PREFIX_INCOMING "<<"
+
+void lanplus_dump_open_session_response(const struct ipmi_rs * rsp)
+{
+ if (verbose < 2)
+ return;
+
+ printf("%sOPEN SESSION RESPONSE\n", DUMP_PREFIX_INCOMING);
+
+ printf("%s Message tag : 0x%02x\n",
+ DUMP_PREFIX_INCOMING,
+ rsp->payload.open_session_response.message_tag);
+ printf("%s RMCP+ status : %s\n",
+ DUMP_PREFIX_INCOMING,
+ val2str(rsp->payload.open_session_response.rakp_return_code,
+ ipmi_rakp_return_codes));
+ printf("%s Maximum privilege level : %s\n",
+ DUMP_PREFIX_INCOMING,
+ val2str(rsp->payload.open_session_response.max_priv_level,
+ ipmi_priv_levels));
+ printf("%s Console Session ID : 0x%08lx\n",
+ DUMP_PREFIX_INCOMING,
+ (long)rsp->payload.open_session_response.console_id);
+
+ /* only tag, status, privlvl, and console id are returned if error */
+ if (rsp->payload.open_session_response.rakp_return_code !=
+ IPMI_RAKP_STATUS_NO_ERRORS)
+ return;
+
+ printf("%s BMC Session ID : 0x%08lx\n",
+ DUMP_PREFIX_INCOMING,
+ (long)rsp->payload.open_session_response.bmc_id);
+ printf("%s Negotiated authenticatin algorithm : %s\n",
+ DUMP_PREFIX_INCOMING,
+ val2str(rsp->payload.open_session_response.auth_alg,
+ ipmi_auth_algorithms));
+ printf("%s Negotiated integrity algorithm : %s\n",
+ DUMP_PREFIX_INCOMING,
+ val2str(rsp->payload.open_session_response.integrity_alg,
+ ipmi_integrity_algorithms));
+ printf("%s Negotiated encryption algorithm : %s\n",
+ DUMP_PREFIX_INCOMING,
+ val2str(rsp->payload.open_session_response.crypt_alg,
+ ipmi_encryption_algorithms));
+ printf("\n");
+}
+
+
+
+void lanplus_dump_rakp2_message(const struct ipmi_rs * rsp, uint8_t auth_alg)
+{
+ int i;
+
+ if (verbose < 2)
+ return;
+
+ printf("%sRAKP 2 MESSAGE\n", DUMP_PREFIX_INCOMING);
+
+ printf("%s Message tag : 0x%02x\n",
+ DUMP_PREFIX_INCOMING,
+ rsp->payload.rakp2_message.message_tag);
+
+ printf("%s RMCP+ status : %s\n",
+ DUMP_PREFIX_INCOMING,
+ val2str(rsp->payload.rakp2_message.rakp_return_code,
+ ipmi_rakp_return_codes));
+
+ printf("%s Console Session ID : 0x%08lx\n",
+ DUMP_PREFIX_INCOMING,
+ (long)rsp->payload.rakp2_message.console_id);
+
+ printf("%s BMC GUID : 0x", DUMP_PREFIX_INCOMING);
+ for (i = 0; i < 16; ++i)
+ printf("%02x", rsp->payload.rakp2_message.bmc_guid[i]);
+ printf("\n");
+
+ switch(auth_alg)
+ {
+ case IPMI_AUTH_RAKP_NONE:
+ printf("%s Key exchange auth code : none\n", DUMP_PREFIX_INCOMING);
+ break;
+ case IPMI_AUTH_RAKP_HMAC_SHA1:
+ case IPMI_AUTH_RAKP_HMAC_MD5:
+ case IPMI_AUTH_RAKP_HMAC_SHA256:
+ printf("%s Key exchange auth code : ok\n", DUMP_PREFIX_INCOMING);
+ break;
+ default:
+ printf("%s Key exchange auth code : invalid", DUMP_PREFIX_INCOMING);
+ }
+ printf("\n");
+}
+
+
+
+void lanplus_dump_rakp4_message(const struct ipmi_rs * rsp, uint8_t auth_alg)
+{
+ //int i;
+
+ if (verbose < 2)
+ return;
+
+ printf("%sRAKP 4 MESSAGE\n", DUMP_PREFIX_INCOMING);
+
+ printf("%s Message tag : 0x%02x\n",
+ DUMP_PREFIX_INCOMING,
+ rsp->payload.rakp4_message.message_tag);
+
+ printf("%s RMCP+ status : %s\n",
+ DUMP_PREFIX_INCOMING,
+ val2str(rsp->payload.rakp4_message.rakp_return_code,
+ ipmi_rakp_return_codes));
+
+ printf("%s Console Session ID : 0x%08lx\n",
+ DUMP_PREFIX_INCOMING,
+ (long)rsp->payload.rakp4_message.console_id);
+
+ switch(auth_alg)
+ {
+ case IPMI_AUTH_RAKP_NONE:
+ printf("%s Key exchange auth code : none\n", DUMP_PREFIX_INCOMING);
+ break;
+ case IPMI_AUTH_RAKP_HMAC_SHA1:
+ case IPMI_AUTH_RAKP_HMAC_MD5:
+ case IPMI_AUTH_RAKP_HMAC_SHA256:
+ printf("%s Key exchange auth code : ok\n", DUMP_PREFIX_INCOMING);
+ break;
+ default:
+ printf("%s Key exchange auth code : invalid", DUMP_PREFIX_INCOMING);
+ }
+ printf("\n");
+}
+
diff --git a/lib/lanplus/lanplus_dump.h b/lib/lanplus/lanplus_dump.h
new file mode 100644
index 0000000..4e29ebb
--- /dev/null
+++ b/lib/lanplus/lanplus_dump.h
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+
+#ifndef IPMI_LANPLUS_DUMP_H
+#define IPMI_LANPLUS_DUMP_H
+
+#include <ipmitool/ipmi_intf.h>
+
+/* See the implementation file for documentation */
+void lanplus_dump_open_session_response(const struct ipmi_rs * rsp);
+void lanplus_dump_rakp2_message(const struct ipmi_rs * rsp, uint8_t auth_alg);
+void lanplus_dump_rakp4_message(const struct ipmi_rs * rsp, uint8_t auth_alg);
+
+
+#endif /* IPMI_LANPLUS_DUMP_H */
diff --git a/lib/lanplus/lanplus_strings.c b/lib/lanplus/lanplus_strings.c
new file mode 100644
index 0000000..f65054f
--- /dev/null
+++ b/lib/lanplus/lanplus_strings.c
@@ -0,0 +1,45 @@
+/*
+ * lanplus_strings.c
+ * extracts all lanplus string messages to one location for potential
+ * customization or translation.
+ *
+ * 01/09/2007 ARCress - created
+ */
+#include "lanplus.h"
+#include "ipmitool/ipmi_constants.h"
+
+const struct valstr ipmi_rakp_return_codes[] = {
+
+ { IPMI_RAKP_STATUS_NO_ERRORS, "no errors" },
+ { IPMI_RAKP_STATUS_INSUFFICIENT_RESOURCES_FOR_SESSION, "insufficient resources for session" },
+ { IPMI_RAKP_STATUS_INVALID_SESSION_ID, "invalid session ID" },
+ { IPMI_RAKP_STATUS_INVALID_PAYLOAD_TYPE, "invalid payload type" },
+ { IPMI_RAKP_STATUS_INVALID_AUTHENTICATION_ALGORITHM, "invalid authentication algorithm" },
+ { IPMI_RAKP_STATUS_INVALID_INTEGRITTY_ALGORITHM, "invalid integrity algorithm" },
+ { IPMI_RAKP_STATUS_NO_MATCHING_AUTHENTICATION_PAYLOAD, "no matching authentication algorithm"},
+ { IPMI_RAKP_STATUS_NO_MATCHING_INTEGRITY_PAYLOAD, "no matching integrity payload" },
+ { IPMI_RAKP_STATUS_INACTIVE_SESSION_ID, "inactive session ID" },
+ { IPMI_RAKP_STATUS_INVALID_ROLE, "invalid role" },
+ { IPMI_RAKP_STATUS_UNAUTHORIZED_ROLE_REQUESTED, "unauthorized role requested" },
+ { IPMI_RAKP_STATUS_INSUFFICIENT_RESOURCES_FOR_ROLE, "insufficient resources for role" },
+ { IPMI_RAKP_STATUS_INVALID_NAME_LENGTH, "invalid name length" },
+ { IPMI_RAKP_STATUS_UNAUTHORIZED_NAME, "unauthorized name" },
+ { IPMI_RAKP_STATUS_UNAUTHORIZED_GUID, "unauthorized GUID" },
+ { IPMI_RAKP_STATUS_INVALID_INTEGRITY_CHECK_VALUE, "invalid integrity check value" },
+ { IPMI_RAKP_STATUS_INVALID_CONFIDENTIALITY_ALGORITHM, "invalid confidentiality algorithm" },
+ { IPMI_RAKP_STATUS_NO_CIPHER_SUITE_MATCH, "no matching cipher suite" },
+ { IPMI_RAKP_STATUS_ILLEGAL_PARAMTER, "illegal parameter" },
+ { 0, 0 },
+};
+
+const struct valstr ipmi_priv_levels[] = {
+ { IPMI_PRIV_CALLBACK, "callback" },
+ { IPMI_PRIV_USER, "user" },
+ { IPMI_PRIV_OPERATOR, "operator" },
+ { IPMI_PRIV_ADMIN, "admin" },
+ { IPMI_PRIV_OEM, "oem" },
+ { 0, 0 },
+};
+
+
+
diff --git a/lib/lanplus/libipmi_lanplus.la b/lib/lanplus/libipmi_lanplus.la
new file mode 100644
index 0000000..870fff8
--- /dev/null
+++ b/lib/lanplus/libipmi_lanplus.la
@@ -0,0 +1,35 @@
+# libipmi_lanplus.la - a libtool library file
+# Generated by ltmain.sh - GNU libtool 1.5.6 (1.1220.2.95 2004/04/11 05:50:42)
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='libipmi_lanplus.so.0'
+
+# Names of this library.
+library_names='libipmi_lanplus.so.0.0.0 libipmi_lanplus.so.0 libipmi_lanplus.so'
+
+# The name of the static archive.
+old_library='libipmi_lanplus.a'
+
+# Libraries that this one depends upon.
+dependency_libs=' -lcrypto'
+
+# Version information for libipmi_lanplus.
+current=0
+age=0
+revision=0
+
+# Is this an already installed library?
+installed=no
+
+# Should we warn about portability when linking against -modules?
+shouldnotlink=no
+
+# Files to dlopen/dlpreopen
+dlopen=''
+dlpreopen=''
+
+# Directory that this library needs to be installed in:
+libdir='/usr/lib'
diff --git a/lib/lanplus/rmcp.h b/lib/lanplus/rmcp.h
new file mode 100644
index 0000000..99b877d
--- /dev/null
+++ b/lib/lanplus/rmcp.h
@@ -0,0 +1,88 @@
+/*
+ * 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.
+ */
+
+#ifndef IPMI_RMCP_H
+#define IPMI_RMCP_H
+
+#include <ipmitool/helper.h>
+#include "lanplus.h"
+
+#define RMCP_VERSION_1 0x06
+
+#define RMCP_UDP_PORT 0x26f /* port 623 */
+#define RMCP_UDP_SECURE_PORT 0x298 /* port 664 */
+
+#define RMCP_TYPE_MASK 0x80
+#define RMCP_TYPE_NORM 0x00
+#define RMCP_TYPE_ACK 0x01
+
+static const struct valstr rmcp_type_vals[] __attribute__((unused)) = {
+ { RMCP_TYPE_NORM, "Normal RMCP" },
+ { RMCP_TYPE_ACK, "RMCP ACK" },
+ { 0, NULL }
+};
+
+#define RMCP_CLASS_MASK 0x1f
+#define RMCP_CLASS_ASF 0x06
+#define RMCP_CLASS_IPMI 0x07
+#define RMCP_CLASS_OEM 0x08
+
+static const struct valstr rmcp_class_vals[] __attribute__((unused)) = {
+ { RMCP_CLASS_ASF, "ASF" },
+ { RMCP_CLASS_IPMI, "IPMI" },
+ { RMCP_CLASS_OEM, "OEM" },
+ { 0, NULL }
+};
+
+/* RMCP message header */
+#ifdef GCC_42
+struct rmcp_hdr {
+ uint8_t ver;
+ uint8_t __rsvd;
+ uint8_t seq;
+ uint8_t class;
+} __attribute__((packed));
+#else
+/* pragma pack works in gcc-4.3 */
+#pragma pack(1)
+struct rmcp_hdr {
+ uint8_t ver;
+ uint8_t __rsvd;
+ uint8_t seq;
+ uint8_t class;
+};
+#pragma pack()
+#endif
+
+int handle_rmcp(struct ipmi_intf * intf, uint8_t * data, int data_len);
+
+#endif /* IPMI_RMCP_H */
diff --git a/lib/libimbapi64.a.redhat b/lib/libimbapi64.a.redhat
new file mode 100644
index 0000000..bd08db1
--- /dev/null
+++ b/lib/libimbapi64.a.redhat
Binary files differ
diff --git a/lib/libimbapi64.a.suse b/lib/libimbapi64.a.suse
new file mode 100644
index 0000000..227ad75
--- /dev/null
+++ b/lib/libimbapi64.a.suse
Binary files differ