summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am40
-rw-r--r--README.md9
-rwxr-xr-xbootstrap.sh18
-rw-r--r--configure.ac30
-rw-r--r--main.cpp193
-rw-r--r--socket_channel.cpp2
-rw-r--r--socket_channel.hpp4
7 files changed, 293 insertions, 3 deletions
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..fb28cad
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,40 @@
+sbin_PROGRAMS = \
+ netipmid
+
+netipmid_SOURCES = \
+ endian.hpp \
+ socket_channel.hpp \
+ socket_channel.cpp \
+ message.hpp \
+ auth_algo.hpp \
+ auth_algo.cpp \
+ session.hpp \
+ session.cpp \
+ sessions_manager.hpp \
+ sessions_manager.cpp \
+ message_parsers.hpp \
+ message_parsers.cpp \
+ message_handler.hpp \
+ message_handler.cpp \
+ command_table.hpp \
+ command_table.cpp \
+ command/channel_auth.hpp \
+ command/channel_auth.cpp \
+ command/guid.hpp \
+ command/guid.cpp \
+ command/open_session.hpp \
+ command/open_session.cpp \
+ command/rakp12.hpp \
+ command/rakp12.cpp \
+ command/rakp34.hpp \
+ command/rakp34.cpp \
+ command/session_cmds.hpp \
+ command/session_cmds.cpp \
+ comm_module.hpp \
+ comm_module.cpp \
+ main.hpp \
+ main.cpp \
+
+netipmid_LDFLAGS = $(SYSTEMD_LIBS) $(CRYPTO_LIBS) $(libmapper_LIBS)
+netipmid_CXXFLAGS = $(SYSTEMD_CFLAGS) $(libmapper_CFLAGS)
+
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..a352eed
--- /dev/null
+++ b/README.md
@@ -0,0 +1,9 @@
+## To Build
+```
+To build this package, do the following steps:
+
+ 1. ./bootstrap.sh
+ 2. ./configure ${CONFIGURE_FLAGS}
+ 3. make
+
+To full clean the repository again run `./bootstrap.sh clean`.
diff --git a/bootstrap.sh b/bootstrap.sh
new file mode 100755
index 0000000..50b75b7
--- /dev/null
+++ b/bootstrap.sh
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+AUTOCONF_FILES="Makefile.in aclocal.m4 ar-lib autom4te.cache compile \
+ config.guess config.h.in config.sub configure depcomp install-sh \
+ ltmain.sh missing *libtool test-driver"
+
+case $1 in
+ clean)
+ test -f Makefile && make maintainer-clean
+ for file in ${AUTOCONF_FILES}; do
+ find -name "$file" | xargs -r rm -rf
+ done
+ exit 0
+ ;;
+esac
+
+autoreconf -i
+echo 'Run "./configure ${CONFIGURE_FLAGS} && make"'
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..1b12c59
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,30 @@
+# Initialization
+AC_PREREQ([2.69])
+AC_INIT([phosphor-net-ipmid], [1.0], [https://github.com/openbmc/phosphor-net-ipmid/issues])
+AC_CONFIG_HEADERS([config.h])
+AM_INIT_AUTOMAKE([subdir-objects -Wall -Werror foreign dist-xz])
+AM_SILENT_RULES([yes])
+
+# Checks for programs.
+AC_PROG_CXX
+AM_PROG_AR
+AC_PROG_INSTALL
+AC_PROG_MAKE_SET
+
+# Surpress the --with-libtool-sysroot error
+LT_INIT
+
+# Checks for typedefs, structures, and compiler characteristics.
+AX_CXX_COMPILE_STDCXX_14([noext])
+AX_APPEND_COMPILE_FLAGS([-Wall -Werror], [CXXFLAGS])
+
+# Checks for libraries.
+PKG_CHECK_MODULES([SYSTEMD], [libsystemd >= 221])
+PKG_CHECK_MODULES([CRYPTO], [libcrypto >= 1.0.2g], ,[AC_MSG_ERROR([can't find openssl libcrypto])])
+AC_CHECK_LIB([mapper], [mapper_get_service], ,[AC_MSG_ERROR([Could not find libmapper...openbmc/phosphor-objmgr package required])])
+
+# Checks for header files.
+AC_CHECK_HEADER(systemd/sd-bus.h, ,[AC_MSG_ERROR([Could not find systemd/sd-bus.h...systemd developement package required])])
+
+AC_CONFIG_FILES([Makefile])
+AC_OUTPUT
diff --git a/main.cpp b/main.cpp
new file mode 100644
index 0000000..0fae8a7
--- /dev/null
+++ b/main.cpp
@@ -0,0 +1,193 @@
+#include "main.hpp"
+#include <assert.h>
+#include <dlfcn.h>
+#include <dirent.h>
+#include <unistd.h>
+
+#include <iostream>
+#include <tuple>
+
+#include <systemd/sd-bus.h>
+#include <systemd/sd-daemon.h>
+#include <systemd/sd-event.h>
+
+#include <host-ipmid/ipmid-api.h>
+#include "comm_module.hpp"
+#include "command_table.hpp"
+#include "message.hpp"
+#include "message_handler.hpp"
+#include "sessions_manager.hpp"
+#include "socket_channel.hpp"
+
+// Tuple of Global Singletons
+session::Manager manager;
+command::Table table;
+std::tuple<session::Manager&, command::Table&> singletonPool(manager, table);
+
+sd_bus* bus = nullptr;
+
+/*
+ * @brief Required by apphandler IPMI Provider Library
+ */
+sd_bus* ipmid_get_sd_bus_connection()
+{
+ return bus;
+}
+
+/*
+ * TODO : The plan is to refactor the event loop to support adding multiple
+ * file descriptors and event handlers for implementing the Serial Over LAN.
+ *
+ * A class would abstract the features provided by the sd_event_loop
+ */
+
+namespace eventloop
+{
+
+static int io_handler(sd_event_source* es, int fd, uint32_t revents,
+ void* userdata)
+{
+ std::shared_ptr<udpsocket::Channel> channelPtr;
+ struct timeval timeout;
+ timeout.tv_sec = SELECT_CALL_TIMEOUT;
+ timeout.tv_usec = 0;
+
+ channelPtr.reset(new udpsocket::Channel(fd, timeout));
+
+ // Initialize the Message Handler with the socket channel
+ message::Handler msgHandler(channelPtr);
+
+ // Read the incoming IPMI packet
+ std::unique_ptr<message::Message> inMessage;
+ try
+ {
+ inMessage = msgHandler.receive();
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Reading & Parsing the incoming IPMI message failed\n";
+ std::cerr << e.what() << "\n";
+ return 0;
+ }
+
+ // Execute the Command
+ auto outMessage = msgHandler.executeCommand(*inMessage.get());
+ if (outMessage == nullptr)
+ {
+ std::cerr << "Execution of IPMI command failed\n";
+ return 0;
+ }
+
+ // Send the response IPMI Message
+ msgHandler.send(*outMessage.get());
+
+ return 0;
+}
+
+int startEventLoop()
+{
+ struct sockaddr_in6 in {};
+
+ sd_event_source* event_source = nullptr;
+ sd_event* event = nullptr;
+ int fd = -1, r;
+ sigset_t ss;
+
+ r = sd_event_default(&event);
+ if (r < 0)
+ {
+ goto finish;
+ }
+
+ if (sigemptyset(&ss) < 0 || sigaddset(&ss, SIGTERM) < 0 ||
+ sigaddset(&ss, SIGINT) < 0)
+ {
+ r = -errno;
+ goto finish;
+ }
+
+ /* Block SIGTERM first, so that the event loop can handle it */
+ if (sigprocmask(SIG_BLOCK, &ss, nullptr) < 0)
+ {
+ r = -errno;
+ goto finish;
+ }
+
+ /* Let's make use of the default handler and "floating" reference features
+ * of sd_event_add_signal() */
+ r = sd_event_add_signal(event, nullptr, SIGTERM, nullptr, nullptr);
+ if (r < 0)
+ {
+ goto finish;
+ }
+
+ r = sd_event_add_signal(event, nullptr, SIGINT, nullptr, nullptr);
+ if (r < 0)
+ {
+ goto finish;
+ }
+
+ fd = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
+ if (fd < 0)
+ {
+ r = -errno;
+ goto finish;
+ }
+
+ in.sin6_family = AF_INET6;
+ in.sin6_port = htons(IPMI_STD_PORT);
+
+ if (bind(fd, (struct sockaddr*)&in, sizeof(in)) < 0)
+ {
+ r = -errno;
+ goto finish;
+ }
+
+ r = sd_event_add_io(event, &event_source, fd, EPOLLIN, io_handler, nullptr);
+ if (r < 0)
+ {
+ goto finish;
+ }
+
+ r = sd_event_loop(event);
+
+finish:
+ event_source = sd_event_source_unref(event_source);
+ event = sd_event_unref(event);
+
+ if (fd >= 0)
+ {
+ (void) close(fd);
+ }
+
+ if (r < 0)
+ {
+ fprintf(stderr, "Failure: %s\n", strerror(-r));
+ }
+
+ return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+}
+
+} // namespace eventloop
+
+int main(int i_argc, char* i_argv[])
+{
+ // Connect to system bus
+ auto rc = sd_bus_open_system(&bus);
+ if (rc < 0)
+ {
+ std::cerr << "Failed to connect to system bus:" << strerror(-rc) <<"\n";
+ goto finish;
+ }
+
+ // Register the phosphor-net-ipmid session setup commands
+ command::sessionSetupCommands();
+
+ // Start Event Loop
+ return eventloop::startEventLoop();
+
+finish:
+ sd_bus_unref(bus);
+
+ return 0;
+}
diff --git a/socket_channel.cpp b/socket_channel.cpp
index 4a6d827..a29ef8d 100644
--- a/socket_channel.cpp
+++ b/socket_channel.cpp
@@ -15,7 +15,7 @@ namespace udpsocket
std::string Channel::getRemoteAddress() const
{
char tmp[INET_ADDRSTRLEN] = { 0 };
- inet_ntop(AF_INET, &address.inAddr.sin_addr, tmp, sizeof(tmp));
+ inet_ntop(AF_INET6, &address.inAddr.sin6_addr, tmp, sizeof(tmp));
return std::string(tmp);
}
diff --git a/socket_channel.hpp b/socket_channel.hpp
index de95bfd..d5f140e 100644
--- a/socket_channel.hpp
+++ b/socket_channel.hpp
@@ -24,7 +24,7 @@ class Channel
union
{
sockaddr sockAddr;
- sockaddr_in inAddr;
+ sockaddr_in6 inAddr;
};
size_t addrSize;
};
@@ -65,7 +65,7 @@ class Channel
*/
auto getPort() const
{
- return address.inAddr.sin_port;
+ return address.inAddr.sin6_port;
}
/**
OpenPOWER on IntegriCloud