From 392050fa407b35b0ac5c0a3172d36d7e30d5b074 Mon Sep 17 00:00:00 2001 From: Vernon Mauery Date: Mon, 1 Apr 2019 14:53:19 -0700 Subject: remove legacy ipmid.cpp and ipmid.hpp These two files have now been replaced with newer APIs and can be removed. Change-Id: If60227b24188c6796211ca43379169f9a95c9cb3 Signed-off-by: Vernon Mauery --- app/channel.hpp | 3 +- app/watchdog.cpp | 1 - apphandler.cpp | 1 - chassishandler.cpp | 1 - groupext.cpp | 2 - include/ipmid/api.h | 4 + ipmid.cpp | 703 --------------------------------------------------- ipmid.hpp | 24 -- sensorhandler.cpp | 1 - transporthandler.cpp | 1 - 10 files changed, 6 insertions(+), 735 deletions(-) delete mode 100644 ipmid.cpp delete mode 100644 ipmid.hpp diff --git a/app/channel.hpp b/app/channel.hpp index 1b761f8..7004ddd 100644 --- a/app/channel.hpp +++ b/app/channel.hpp @@ -1,6 +1,7 @@ -#include "ipmid.hpp" #include "nlohmann/json.hpp" +#include + /** @brief The set channel access IPMI command. * * @param[in] netfn diff --git a/app/watchdog.cpp b/app/watchdog.cpp index 1a5d19c..68af65c 100644 --- a/app/watchdog.cpp +++ b/app/watchdog.cpp @@ -1,6 +1,5 @@ #include "watchdog.hpp" -#include "ipmid.hpp" #include "watchdog_service.hpp" #include diff --git a/apphandler.cpp b/apphandler.cpp index e5daa2a..8875cd8 100644 --- a/apphandler.cpp +++ b/apphandler.cpp @@ -2,7 +2,6 @@ #include "app/channel.hpp" #include "app/watchdog.hpp" -#include "ipmid.hpp" #include "sys_info_param.hpp" #include "transporthandler.hpp" diff --git a/chassishandler.cpp b/chassishandler.cpp index 07e8c5b..7ac7b7d 100644 --- a/chassishandler.cpp +++ b/chassishandler.cpp @@ -2,7 +2,6 @@ #include "chassishandler.hpp" -#include "ipmid.hpp" #include "settings.hpp" #include diff --git a/groupext.cpp b/groupext.cpp index 7b4ca5e..dbfade4 100644 --- a/groupext.cpp +++ b/groupext.cpp @@ -1,5 +1,3 @@ -#include "ipmid.hpp" - #include #include diff --git a/include/ipmid/api.h b/include/ipmid/api.h index b1c078b..f08ee11 100644 --- a/include/ipmid/api.h +++ b/include/ipmid/api.h @@ -152,4 +152,8 @@ sd_bus* ipmid_get_sd_bus_connection(void); sd_event* ipmid_get_sd_event_connection(void); sd_bus_slot* ipmid_get_sd_bus_slot(void); +// move this from ipmid.hpp, which is now gone +// this should not be used. Use the channel API to get the channel size +#define MAX_IPMI_BUFFER 64 + #endif diff --git a/ipmid.cpp b/ipmid.cpp deleted file mode 100644 index e5860d0..0000000 --- a/ipmid.cpp +++ /dev/null @@ -1,703 +0,0 @@ -#include "config.h" - -#include "ipmid.hpp" - -#include "host-cmd-manager.hpp" -#include "ipmiwhitelist.hpp" -#include "sensorhandler.hpp" -#include "settings.hpp" - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace phosphor::logging; -namespace sdbusRule = sdbusplus::bus::match::rules; -namespace variant_ns = sdbusplus::message::variant_ns; - -sd_bus* bus = NULL; -sd_bus_slot* ipmid_slot = NULL; -sd_event* events = nullptr; - -// Need this to use new sdbusplus compatible interfaces -sdbusPtr sdbusp; - -// Global Host Bound Command manager -using cmdManagerPtr = std::unique_ptr; -cmdManagerPtr cmdManager; - -// Global timer for network changes -std::unique_ptr networkTimer = nullptr; - -// Command and handler tuple. Used when clients ask the command to be put -// into host message queue -using CommandHandler = phosphor::host::command::CommandHandler; - -// Initialise restricted mode to true -bool restricted_mode = true; - -FILE *ipmiio, *ipmidbus, *ipmicmddetails; - -void print_usage(void) -{ - std::fprintf(stderr, "Options: [-d mask]\n"); - std::fprintf(stderr, " mask : 0x01 - Print ipmi packets\n"); - std::fprintf(stderr, " mask : 0x02 - Print DBUS operations\n"); - std::fprintf(stderr, " mask : 0x04 - Print ipmi command details\n"); - std::fprintf(stderr, " mask : 0xFF - Print all trace\n"); -} - -const char* DBUS_INTF = "org.openbmc.HostIpmi"; - -const char* FILTER = - "type='signal',interface='org.openbmc.HostIpmi',member='ReceivedMessage'"; - -typedef std::pair ipmi_fn_cmd_t; -typedef std::pair ipmi_fn_context_t; - -// Global data structure that contains the IPMI command handler's registrations. -std::map g_ipmid_router_map; - -// IPMI Spec, shared Reservation ID. -static unsigned short selReservationID = 0xFFFF; -static bool selReservationValid = false; - -unsigned short reserveSel(void) -{ - // IPMI spec, Reservation ID, the value simply increases against each - // execution of the Reserve SEL command. - if (++selReservationID == 0) - { - selReservationID = 1; - } - selReservationValid = true; - return selReservationID; -} - -bool checkSELReservation(unsigned short id) -{ - return (selReservationValid && selReservationID == id); -} - -void cancelSELReservation(void) -{ - selReservationValid = false; -} - -namespace internal -{ - -constexpr auto restrictionModeIntf = - "xyz.openbmc_project.Control.Security.RestrictionMode"; - -namespace cache -{ - -std::unique_ptr objects = nullptr; - -} // namespace cache -} // namespace internal - -#ifndef HEXDUMP_COLS -#define HEXDUMP_COLS 16 -#endif - -void hexdump(FILE* s, void* mem, size_t len) -{ - unsigned int i, j; - - for (i = 0; - i < - len + ((len % HEXDUMP_COLS) ? (HEXDUMP_COLS - len % HEXDUMP_COLS) : 0); - i++) - { - /* print offset */ - if (i % HEXDUMP_COLS == 0) - { - std::fprintf(s, "0x%06x: ", i); - } - - /* print hex data */ - if (i < len) - { - std::fprintf(s, "%02x ", 0xFF & ((char*)mem)[i]); - } - else /* end of block, just aligning for ASCII dump */ - { - std::fprintf(s, " "); - } - - /* print ASCII dump */ - if (i % HEXDUMP_COLS == (HEXDUMP_COLS - 1)) - { - for (j = i - (HEXDUMP_COLS - 1); j <= i; j++) - { - if (j >= len) /* end of block, not really printing */ - { - std::fputc(' ', s); - } - else if (std::isprint(((char*)mem)[j])) /* printable char */ - { - std::fputc(0xFF & ((char*)mem)[j], s); - } - else /* other char */ - { - std::fputc('.', s); - } - } - std::fputc('\n', s); - } - } -} - -// Method that gets called by shared libraries to get their command handlers -// registered -void ipmi_register_callback(ipmi_netfn_t netfn, ipmi_cmd_t cmd, - ipmi_context_t context, ipmid_callback_t handler, - ipmi_cmd_privilege_t priv) -{ - // Pack NetFn and Command in one. - auto netfn_and_cmd = std::make_pair(netfn, cmd); - - // Pack Function handler and Data in another. - auto handler_and_context = std::make_pair(handler, context); - - // Check if the registration has already been made.. - auto iter = g_ipmid_router_map.find(netfn_and_cmd); - if (iter != g_ipmid_router_map.end()) - { - log("Duplicate registration", entry("NETFN=0x%X", netfn), - entry("CMD=0x%X", cmd)); - } - else - { - // This is a fresh registration.. Add it to the map. - g_ipmid_router_map.emplace(netfn_and_cmd, handler_and_context); - } - - return; -} - -// Looks at the map and calls corresponding handler functions. -ipmi_ret_t ipmi_netfn_router(ipmi_netfn_t netfn, ipmi_cmd_t cmd, - ipmi_request_t request, ipmi_response_t response, - ipmi_data_len_t data_len) -{ - // return from the Command handlers. - ipmi_ret_t rc = IPMI_CC_INVALID; - - // If restricted mode is true and command is not whitelisted, don't - // execute the command - if (restricted_mode) - { - if (!std::binary_search(whitelist.cbegin(), whitelist.cend(), - std::make_pair(netfn, cmd))) - { - log("Net function not whitelisted", - entry("NETFN=0x%X", netfn), entry("CMD=0x%X", cmd)); - rc = IPMI_CC_INSUFFICIENT_PRIVILEGE; - std::memcpy(response, &rc, IPMI_CC_LEN); - *data_len = IPMI_CC_LEN; - return rc; - } - } - - // Walk the map that has the registered handlers and invoke the approprite - // handlers for matching commands. - auto iter = g_ipmid_router_map.find(std::make_pair(netfn, cmd)); - if (iter == g_ipmid_router_map.end()) - { - /* By default should only print on failure to find wildcard command. */ -#ifdef __IPMI_DEBUG__ - log( - "No registered handlers for NetFn, trying Wilcard implementation", - entry("NET_FUN=0x%X", netfn) entry("CMD=0x%X", IPMI_CMD_WILDCARD)); -#endif - - // Now that we did not find any specific [NetFn,Cmd], tuple, check for - // NetFn, WildCard command present. - iter = - g_ipmid_router_map.find(std::make_pair(netfn, IPMI_CMD_WILDCARD)); - if (iter == g_ipmid_router_map.end()) - { - log("No Registered handlers for NetFn", - entry("NET_FUN=0x%X", netfn), - entry("CMD=0x%X", IPMI_CMD_WILDCARD)); - - // Respond with a 0xC1 - std::memcpy(response, &rc, IPMI_CC_LEN); - *data_len = IPMI_CC_LEN; - return rc; - } - } - -#ifdef __IPMI_DEBUG__ - // We have either a perfect match -OR- a wild card atleast, - log("Calling Net function", - entry("NET_FUN=0x%X", netfn) entry("CMD=0x%X", cmd)); -#endif - - // Extract the map data onto appropriate containers - auto handler_and_context = iter->second; - - // Creating a pointer type casted to char* to make sure we advance 1 byte - // when we advance pointer to next's address. advancing void * would not - // make sense. - char* respo = &((char*)response)[IPMI_CC_LEN]; - - try - { - // Response message from the plugin goes into a byte post the base - // response - rc = (handler_and_context.first)(netfn, cmd, request, respo, data_len, - handler_and_context.second); - } - // IPMI command handlers can throw unhandled exceptions, catch those - // and return sane error code. - catch (const std::exception& e) - { - log(e.what(), entry("NET_FUN=0x%X", netfn), - entry("CMD=0x%X", cmd)); - rc = IPMI_CC_UNSPECIFIED_ERROR; - *data_len = 0; - // fall through - } - // Now copy the return code that we got from handler and pack it in first - // byte. - std::memcpy(response, &rc, IPMI_CC_LEN); - - // Data length is now actual data + completion code. - *data_len = *data_len + IPMI_CC_LEN; - - return rc; -} - -static int send_ipmi_message(sd_bus_message* req, unsigned char seq, - unsigned char netfn, unsigned char lun, - unsigned char cmd, unsigned char cc, - unsigned char* buf, unsigned char len) -{ - - sd_bus_error error = SD_BUS_ERROR_NULL; - sd_bus_message *reply = NULL, *m = NULL; - const char *dest, *path; - int r, pty; - - dest = sd_bus_message_get_sender(req); - path = sd_bus_message_get_path(req); - - r = sd_bus_message_new_method_call(bus, &m, dest, path, DBUS_INTF, - "sendMessage"); - if (r < 0) - { - log("Failed to add the method object", - entry("ERRNO=0x%X", -r)); - return -1; - } - - // Responses in IPMI require a bit set. So there ya go... - netfn |= 0x01; - - // Add the bytes needed for the methods to be called - r = sd_bus_message_append(m, "yyyyy", seq, netfn, lun, cmd, cc); - if (r < 0) - { - log("Failed add the netfn and others", - entry("ERRNO=0x%X", -r)); - goto final; - } - - r = sd_bus_message_append_array(m, 'y', buf, len); - if (r < 0) - { - log("Failed to add the string of response bytes", - entry("ERRNO=0x%X", -r)); - goto final; - } - - // Call the IPMI responder on the bus so the message can be sent to the CEC - r = sd_bus_call(bus, m, 0, &error, &reply); - if (r < 0) - { - log("Failed to call the method", entry("DEST=%s", dest), - entry("PATH=%s", path), entry("ERRNO=0x%X", -r)); - goto final; - } - - r = sd_bus_message_read(reply, "x", &pty); - if (r < 0) - { - log("Failed to get a reply from the method", - entry("ERRNO=0x%X", -r)); - } - -final: - sd_bus_error_free(&error); - m = sd_bus_message_unref(m); - reply = sd_bus_message_unref(reply); - - return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; -} - -void cache_restricted_mode() -{ - restricted_mode = false; - using namespace sdbusplus::xyz::openbmc_project::Control::Security::server; - using namespace internal; - using namespace internal::cache; - sdbusplus::bus::bus dbus(ipmid_get_sd_bus_connection()); - const auto& restrictionModeSetting = - objects->map.at(restrictionModeIntf).front(); - auto method = dbus.new_method_call( - objects->service(restrictionModeSetting, restrictionModeIntf).c_str(), - restrictionModeSetting.c_str(), "org.freedesktop.DBus.Properties", - "Get"); - method.append(restrictionModeIntf, "RestrictionMode"); - auto resp = dbus.call(method); - if (resp.is_method_error()) - { - log("Error in RestrictionMode Get"); - // Fail-safe to true. - restricted_mode = true; - return; - } - sdbusplus::message::variant result; - resp.read(result); - auto restrictionMode = RestrictionMode::convertModesFromString( - variant_ns::get(result)); - if (RestrictionMode::Modes::Whitelist == restrictionMode) - { - restricted_mode = true; - } -} - -static int handle_restricted_mode_change(sd_bus_message* m, void* user_data, - sd_bus_error* ret_error) -{ - cache_restricted_mode(); - return 0; -} - -static int handle_ipmi_command(sd_bus_message* m, void* user_data, - sd_bus_error* ret_error) -{ - int r = 0; - unsigned char sequence, netfn, lun, cmd; - const void* request; - size_t sz; - size_t resplen = MAX_IPMI_BUFFER; - unsigned char response[MAX_IPMI_BUFFER]; - - std::memset(response, 0, MAX_IPMI_BUFFER); - - r = sd_bus_message_read(m, "yyyy", &sequence, &netfn, &lun, &cmd); - if (r < 0) - { - log("Failed to parse signal message", - entry("ERRNO=0x%X", -r)); - return -1; - } - - r = sd_bus_message_read_array(m, 'y', &request, &sz); - if (r < 0) - { - log("Failed to parse signal message", - entry("ERRNO=0x%X", -r)); - return -1; - } - - std::fprintf(ipmiio, - "IPMI Incoming: Seq 0x%02x, NetFn 0x%02x, CMD: 0x%02x \n", - sequence, netfn, cmd); - hexdump(ipmiio, (void*)request, sz); - - // Allow the length field to be used for both input and output of the - // ipmi call - resplen = sz; - - // Now that we have parsed the entire byte array from the caller - // we can call the ipmi router to do the work... - r = ipmi_netfn_router(netfn, cmd, (void*)request, (void*)response, - &resplen); - if (r != 0) - { -#ifdef __IPMI_DEBUG__ - log("ERROR in handling NetFn", entry("ERRNO=0x%X", -r), - entry("NET_FUN=0x%X", netfn), entry("CMD=0x%X", cmd)); -#endif - resplen = 0; - } - else - { - resplen = resplen - 1; // first byte is for return code. - } - - std::fprintf(ipmiio, "IPMI Response:\n"); - hexdump(ipmiio, (void*)response, resplen); - - // Send the response buffer from the ipmi command - r = send_ipmi_message(m, sequence, netfn, lun, cmd, response[0], - ((unsigned char*)response) + 1, resplen); - if (r < 0) - { - log("Failed to send the response message"); - return -1; - } - - return 0; -} - -//---------------------------------------------------------------------- -// handler_select -// Select all the files ending with with .so. in the given diretcory -// @d: dirent structure containing the file name -//---------------------------------------------------------------------- -int handler_select(const struct dirent* entry) -{ - // To hold ".so" from entry->d_name; - char dname_copy[4] = {0}; - - // We want to avoid checking for everything and isolate to the ones having - // .so.* or .so in them. - // Check for versioned libraries .so.* - if (strstr(entry->d_name, IPMI_PLUGIN_SONAME_EXTN)) - { - return 1; - } - // Check for non versioned libraries .so - else if (strstr(entry->d_name, IPMI_PLUGIN_EXTN)) - { - // It is possible that .so could be anywhere in the string but unlikely - // But being careful here. Get the base address of the string, move - // until end and come back 3 steps and that gets what we need. - strcpy(dname_copy, (entry->d_name + strlen(entry->d_name) - - strlen(IPMI_PLUGIN_EXTN))); - if (strcmp(dname_copy, IPMI_PLUGIN_EXTN) == 0) - { - return 1; - } - } - return 0; -} - -// This will do a dlopen of every .so in ipmi_lib_path and will dlopen -// everything so that they will register a callback handler -void ipmi_register_callback_handlers(const char* ipmi_lib_path) -{ - // For walking the ipmi_lib_path - struct dirent** handler_list; - - // This is used to check and abort if someone tries to register a bad one. - void* lib_handler = NULL; - - if (ipmi_lib_path == NULL) - { - log("No handlers to be registered for ipmi.. Aborting"); - assert(0); - } - else - { - // 1: Open ipmi_lib_path. Its usually "/usr/lib/phosphor-host-ipmid" - // 2: Scan the directory for the files that end with .so - // 3: For each one of them, just do a 'dlopen' so that they register - // the handlers for callback routines. - - std::string handler_fqdn = ipmi_lib_path; - - // Append a "/" since we need to add the name of the .so. If there is - // already a .so, adding one more is not any harm. - handler_fqdn += "/"; - - int num_handlers = - scandir(ipmi_lib_path, &handler_list, handler_select, alphasort); - if (num_handlers < 0) - return; - - while (num_handlers--) - { - handler_fqdn = ipmi_lib_path; - handler_fqdn += handler_list[num_handlers]->d_name; -#ifdef __IPMI_DEBUG__ - log("Registering handler", - entry("HANDLER=%s", handler_fqdn.c_str())); -#endif - - lib_handler = dlopen(handler_fqdn.c_str(), RTLD_NOW); - - if (lib_handler == NULL) - { - log("ERROR opening", - entry("HANDLER=%s", handler_fqdn.c_str()), - entry("ERROR=%s", dlerror())); - } - // Wipe the memory allocated for this particular entry. - free(handler_list[num_handlers]); - } - - // Done with all registration. - free(handler_list); - } - - // TODO : What to be done on the memory that is given by dlopen ?. - return; -} - -sd_bus* ipmid_get_sd_bus_connection(void) -{ - return bus; -} - -sd_event* ipmid_get_sd_event_connection(void) -{ - return events; -} - -sd_bus_slot* ipmid_get_sd_bus_slot(void) -{ - return ipmid_slot; -} - -EInterfaceIndex getInterfaceIndex(void) -{ - return interfaceKCS; -} - -// Calls host command manager to do the right thing for the command -void ipmid_send_cmd_to_host(CommandHandler&& cmd) -{ - return cmdManager->execute(std::move(cmd)); -} - -cmdManagerPtr& ipmid_get_host_cmd_manager() -{ - return cmdManager; -} - -sdbusPtr& ipmid_get_sdbus_plus_handler() -{ - return sdbusp; -} - -int main(int argc, char* argv[]) -{ - int r; - unsigned long tvalue; - int c; - - // This file and subsequient switch is for turning on levels - // of trace - ipmicmddetails = ipmiio = ipmidbus = fopen("/dev/null", "w"); - - while ((c = getopt(argc, argv, "h:d:")) != -1) - switch (c) - { - case 'd': - tvalue = strtoul(optarg, NULL, 16); - if (1 & tvalue) - { - ipmiio = stdout; - } - if (2 & tvalue) - { - ipmidbus = stdout; - } - if (4 & tvalue) - { - ipmicmddetails = stdout; - } - break; - case 'h': - case '?': - print_usage(); - return 1; - } - - /* Connect to system bus */ - r = sd_bus_default_system(&bus); - if (r < 0) - { - log("Failed to connect to system bus", - entry("ERRNO=0x%X", -r)); - goto finish; - } - - /* Get an sd event handler */ - r = sd_event_default(&events); - if (r < 0) - { - log("Failure to create sd_event handler", - entry("ERRNO=0x%X", -r)); - goto finish; - } - - // Now create the Host Bound Command manager. Need sdbusplus - // to use the generated bindings - sdbusp = std::make_unique(bus); - sdbusp->request_name("xyz.openbmc_project.Ipmi.Host"); - - cmdManager = std::make_unique(*sdbusp); - - // Activate OemRouter. - oem::mutableRouter()->activate(); - - // Register all the handlers that provider implementation to IPMI commands. - ipmi_register_callback_handlers(HOST_IPMI_LIB_PATH); - - // Watch for BT messages - r = sd_bus_add_match(bus, &ipmid_slot, FILTER, handle_ipmi_command, NULL); - if (r < 0) - { - log("Failed: sd_bus_add_match", entry("FILTER=%s", FILTER), - entry("ERRNO=0x%X", -r)); - goto finish; - } - - // Attach the bus to sd_event to service user requests - sd_bus_attach_event(bus, events, SD_EVENT_PRIORITY_NORMAL); - - { - using namespace internal; - using namespace internal::cache; - sdbusplus::bus::bus dbus{bus}; - objects = std::make_unique( - dbus, std::vector({restrictionModeIntf})); - // Initialize restricted mode - cache_restricted_mode(); - // Wait for changes on Restricted mode - sdbusplus::bus::match_t restrictedModeMatch( - dbus, - sdbusRule::propertiesChanged( - objects->map.at(restrictionModeIntf).front(), - restrictionModeIntf), - handle_restricted_mode_change); - - r = sd_event_loop(events); - } - -finish: - sd_event_unref(events); - sd_bus_detach_event(bus); - sd_bus_slot_unref(ipmid_slot); - sd_bus_unref(bus); - return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; -} diff --git a/ipmid.hpp b/ipmid.hpp deleted file mode 100644 index 93a85b0..0000000 --- a/ipmid.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include -#include - -// When the requester sends in a netfn and a command along with data, this -// function will look for registered handlers that will handle that [netfn,cmd] -// and will make a call to that plugin implementation and send back the -// response. -ipmi_ret_t ipmi_netfn_router(const ipmi_netfn_t, const ipmi_cmd_t, - ipmi_request_t, ipmi_response_t, - unsigned int* data_len); - -// Plugin libraries need to _end_ with .so -#define IPMI_PLUGIN_EXTN ".so" -// Plugin libraries can be versioned with suffix .so.* -#define IPMI_PLUGIN_SONAME_EXTN ".so." - -// The BT FIFO in the AST2400 can only handle 64 bytes. -// Can only allow 63 because the BT interface still -// needs 1 byte for the length field. -#define MAX_IPMI_BUFFER 64 - -extern FILE *ipmiio, *ipmidbus, *ipmicmddetails; diff --git a/sensorhandler.cpp b/sensorhandler.cpp index 4da40af..cf8feaa 100644 --- a/sensorhandler.cpp +++ b/sensorhandler.cpp @@ -1,7 +1,6 @@ #include "sensorhandler.hpp" #include "fruread.hpp" -#include "ipmid.hpp" #include #include diff --git a/transporthandler.cpp b/transporthandler.cpp index 7d678a8..1662530 100644 --- a/transporthandler.cpp +++ b/transporthandler.cpp @@ -1,7 +1,6 @@ #include "transporthandler.hpp" #include "app/channel.hpp" -#include "ipmid.hpp" #include "user_channel/channel_layer.hpp" #include -- cgit v1.2.1