From a7f89980e5b3f4b9a74c70dbc5ffe8aabd28be28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Sun, 6 Jul 2014 18:04:32 +0200 Subject: Imported Upstream version 2.9.3 --- lib/lanplus/Makefile.am | 55 + lib/lanplus/Makefile.in | 532 ++++ lib/lanplus/README | 19 + lib/lanplus/asf.h | 82 + lib/lanplus/helper.c | 480 ++++ lib/lanplus/inc/config.h | 144 + lib/lanplus/inc/inttypes-win.h | 30 + lib/lanplus/inc/ipmitool/bswap.h | 53 + lib/lanplus/inc/ipmitool/helper.h | 102 + lib/lanplus/inc/ipmitool/ipmi.h | 267 ++ lib/lanplus/inc/ipmitool/ipmi_cc.h | 76 + lib/lanplus/inc/ipmitool/ipmi_channel.h | 229 ++ lib/lanplus/inc/ipmitool/ipmi_chassis.h | 55 + lib/lanplus/inc/ipmitool/ipmi_constants.h | 136 + lib/lanplus/inc/ipmitool/ipmi_entity.h | 47 + lib/lanplus/inc/ipmitool/ipmi_event.h | 60 + lib/lanplus/inc/ipmitool/ipmi_firewall.h | 106 + lib/lanplus/inc/ipmitool/ipmi_fru.h | 381 +++ lib/lanplus/inc/ipmitool/ipmi_fwum.h | 46 + lib/lanplus/inc/ipmitool/ipmi_hpmfwupg.h | 45 + lib/lanplus/inc/ipmitool/ipmi_intf.h | 224 ++ lib/lanplus/inc/ipmitool/ipmi_isol.h | 56 + lib/lanplus/inc/ipmitool/ipmi_kontronoem.h | 49 + lib/lanplus/inc/ipmitool/ipmi_lanp.h | 132 + lib/lanplus/inc/ipmitool/ipmi_main.h | 42 + lib/lanplus/inc/ipmitool/ipmi_mc.h | 103 + lib/lanplus/inc/ipmitool/ipmi_oem.h | 47 + lib/lanplus/inc/ipmitool/ipmi_pef.h | 784 ++++++ lib/lanplus/inc/ipmitool/ipmi_picmg.h | 90 + lib/lanplus/inc/ipmitool/ipmi_raw.h | 44 + lib/lanplus/inc/ipmitool/ipmi_sdr.h | 876 ++++++ lib/lanplus/inc/ipmitool/ipmi_sel.h | 542 ++++ lib/lanplus/inc/ipmitool/ipmi_sensor.h | 84 + lib/lanplus/inc/ipmitool/ipmi_session.h | 125 + lib/lanplus/inc/ipmitool/ipmi_sol.h | 84 + lib/lanplus/inc/ipmitool/ipmi_strings.h | 60 + lib/lanplus/inc/ipmitool/ipmi_sunoem.h | 57 + lib/lanplus/inc/ipmitool/ipmi_tsol.h | 46 + lib/lanplus/inc/ipmitool/ipmi_user.h | 89 + lib/lanplus/inc/ipmitool/log.h | 74 + lib/lanplus/ipmi_strings.c | 348 +++ lib/lanplus/ipmiplus.mak | 67 + lib/lanplus/lanplus.c | 4036 ++++++++++++++++++++++++++++ lib/lanplus/lanplus.h | 135 + lib/lanplus/lanplus_crypt.c | 1038 +++++++ lib/lanplus/lanplus_crypt.h | 79 + lib/lanplus/lanplus_crypt_impl.c | 320 +++ lib/lanplus/lanplus_crypt_impl.h | 66 + lib/lanplus/lanplus_defs.h | 376 +++ lib/lanplus/lanplus_dump.c | 174 ++ lib/lanplus/lanplus_dump.h | 45 + lib/lanplus/lanplus_strings.c | 45 + lib/lanplus/libipmi_lanplus.la | 35 + lib/lanplus/rmcp.h | 88 + 54 files changed, 13405 insertions(+) create mode 100644 lib/lanplus/Makefile.am create mode 100644 lib/lanplus/Makefile.in create mode 100644 lib/lanplus/README create mode 100644 lib/lanplus/asf.h create mode 100644 lib/lanplus/helper.c create mode 100644 lib/lanplus/inc/config.h create mode 100644 lib/lanplus/inc/inttypes-win.h create mode 100644 lib/lanplus/inc/ipmitool/bswap.h create mode 100644 lib/lanplus/inc/ipmitool/helper.h create mode 100644 lib/lanplus/inc/ipmitool/ipmi.h create mode 100644 lib/lanplus/inc/ipmitool/ipmi_cc.h create mode 100644 lib/lanplus/inc/ipmitool/ipmi_channel.h create mode 100644 lib/lanplus/inc/ipmitool/ipmi_chassis.h create mode 100644 lib/lanplus/inc/ipmitool/ipmi_constants.h create mode 100644 lib/lanplus/inc/ipmitool/ipmi_entity.h create mode 100644 lib/lanplus/inc/ipmitool/ipmi_event.h create mode 100644 lib/lanplus/inc/ipmitool/ipmi_firewall.h create mode 100644 lib/lanplus/inc/ipmitool/ipmi_fru.h create mode 100644 lib/lanplus/inc/ipmitool/ipmi_fwum.h create mode 100644 lib/lanplus/inc/ipmitool/ipmi_hpmfwupg.h create mode 100644 lib/lanplus/inc/ipmitool/ipmi_intf.h create mode 100644 lib/lanplus/inc/ipmitool/ipmi_isol.h create mode 100644 lib/lanplus/inc/ipmitool/ipmi_kontronoem.h create mode 100644 lib/lanplus/inc/ipmitool/ipmi_lanp.h create mode 100644 lib/lanplus/inc/ipmitool/ipmi_main.h create mode 100644 lib/lanplus/inc/ipmitool/ipmi_mc.h create mode 100644 lib/lanplus/inc/ipmitool/ipmi_oem.h create mode 100644 lib/lanplus/inc/ipmitool/ipmi_pef.h create mode 100644 lib/lanplus/inc/ipmitool/ipmi_picmg.h create mode 100644 lib/lanplus/inc/ipmitool/ipmi_raw.h create mode 100644 lib/lanplus/inc/ipmitool/ipmi_sdr.h create mode 100644 lib/lanplus/inc/ipmitool/ipmi_sel.h create mode 100644 lib/lanplus/inc/ipmitool/ipmi_sensor.h create mode 100644 lib/lanplus/inc/ipmitool/ipmi_session.h create mode 100644 lib/lanplus/inc/ipmitool/ipmi_sol.h create mode 100644 lib/lanplus/inc/ipmitool/ipmi_strings.h create mode 100644 lib/lanplus/inc/ipmitool/ipmi_sunoem.h create mode 100644 lib/lanplus/inc/ipmitool/ipmi_tsol.h create mode 100644 lib/lanplus/inc/ipmitool/ipmi_user.h create mode 100644 lib/lanplus/inc/ipmitool/log.h create mode 100644 lib/lanplus/ipmi_strings.c create mode 100644 lib/lanplus/ipmiplus.mak create mode 100644 lib/lanplus/lanplus.c create mode 100644 lib/lanplus/lanplus.h create mode 100644 lib/lanplus/lanplus_crypt.c create mode 100644 lib/lanplus/lanplus_crypt.h create mode 100644 lib/lanplus/lanplus_crypt_impl.c create mode 100644 lib/lanplus/lanplus_crypt_impl.h create mode 100644 lib/lanplus/lanplus_defs.h create mode 100644 lib/lanplus/lanplus_dump.c create mode 100644 lib/lanplus/lanplus_dump.h create mode 100644 lib/lanplus/lanplus_strings.c create mode 100644 lib/lanplus/libipmi_lanplus.la create mode 100644 lib/lanplus/rmcp.h (limited to 'lib/lanplus') 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 +#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 +#include +#include +#include +#include +#include +#include +#else +#include +#include +#include /* For TIOCNOTTY */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif + +#if HAVE_CONFIG_H +# include +#endif + +#ifdef HAVE_PATHS_H +#include +#else +#define _PATH_VARRUN "/var/run/" +#define _PATH_TTY "/dev/tty" +#endif + +#include +#include +#include +#include + +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 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 header file. */ +#define HAVE_ARPA_INET_H 1 +/* Define to 1 if you have the 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 header file. */ +#define HAVE_DLFCN_H 1 +/* Define to 1 if you have the header file. */ +#define HAVE_FCNTL_H 1 +/* Define to 1 if you have the header file. */ +/* #undef HAVE_FREEBSD_IPMI_H */ +/* Define to 1 if you have the header file. */ +#define HAVE_NETDB_H 1 +/* Define to 1 if you have the header file. */ +#define HAVE_NETINET_IN_H 1 +/* Define to 1 if you have the header file. */ +#define HAVE_OPENIPMI_H 1 +/* Define to 1 if you have the 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 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 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 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 header file. */ +#define HAVE_STDINT_H 1 +/* Define to 1 if you have the 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 header file. */ +#define HAVE_STRINGS_H 1 +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_BYTEORDER_H */ +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_SELECT_H 1 +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_SOCKET_H 1 +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 +/* Define to 1 if you have . */ +/* #undef HAVE_SYS_TERMIOS_H */ +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 +/* Define to 1 if you have . */ +#define HAVE_TERMIOS_H 1 +/* Define to 1 if you have the 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 +#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 +#endif + +#undef BSWAP_16 +#undef BSWAP_32 + +#if HAVE_BYTESWAP_H +# include +# 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 +#include +#include +#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 +#include +#include +#include +#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 +#include +#include +#include +#else +#include +#include +#include +#include +#include +#include +#include +#endif + +#include + +#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 +#endif +#include + + +#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 + +#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 +#endif +#include + +#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 + +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 +#else +#include +#endif +#include +#include + +#if HAVE_CONFIG_H +# include +#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 +#else +#include +#endif +#include + + +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 +#else +#include +#endif +#include + +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 +#include +#include + +#ifdef WIN32 +#include +#include +#include +#else +#include +#include +#include +#include +#endif + +#include +#include + +#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 + +#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 +#else +#include +#endif +#include + + +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 + +#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 + +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 + +#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 + +/* 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 + +/* 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", 1}, /* '>' : getting better */ + {"LC", 3}, + {"LNR", 5}, + {">UNC", 6}, + {"UC", 8}, + {"UNR", 10}, + {"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", 4}, /* '>' : getting better */ + {"non-redundant/insufficient", 5}, + {"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 + +/* 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 + +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 +#endif + +#ifdef WIN32 +#include +#else +#include +#endif +#include +#include +#include +#include + +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 +#else +#include +#endif +#include +#include + +#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 +#include +#include +#include + +/* 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 +#endif +#include + +#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 + +#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 + +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 +#endif +#include +#include + +#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 + +#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 +#endif +#include + + +/* + * 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 + +/* 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 +#include +#include +#include +#include /* 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 +#include +#include +#include +#include +#include +//#define HAVE_IPV6 1 +#ifdef HAVE_IPV6 +#include +//#include +#else +#include +#endif +#include +#else +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif +#if defined(LINUX) +#define HAVE_IPV6 1 +/* TODO: fixups in BSD/Solaris for ipv6 method */ +#endif +#if defined(MACOS) +#include +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 +#include + +#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 +#include +#if defined(HAVE_CONFIG_H) +# include +#endif +#include +#include +#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 + * - 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 + * - 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 + * - 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 + +#include +#include +#include + +/* + * 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 +#include +#include +#include +#include + + + +/* + * 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 +#endif + +#include + +#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 + +/* 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 +#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 */ -- cgit v1.2.3