You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1931 lines
70 KiB

From 6df63fe455745d8d74010d9ad4f85a30f40b5c08 Mon Sep 17 00:00:00 2001
From: Frederic Bohe <fbohe-guest@alioth.debian.org>
Date: Mon, 10 Sep 2012 13:28:35 +0000
Subject: [PATCH] [nut-scanner] Fix a crash when no start IP is provided.
Fossil-ID: SVN r3722
---
tools/nut-scanner/nut-scanner.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/tools/nut-scanner/nut-scanner.c b/tools/nut-scanner/nut-scanner.c
index db582be..52e0da7 100644
--- a/tools/nut-scanner/nut-scanner.c
+++ b/tools/nut-scanner/nut-scanner.c
@@ -371,6 +371,7 @@ display_help:
if( allow_snmp && nutscan_avail_snmp ) {
if( start_ip == NULL ) {
printq(quiet,"No start IP, skipping SNMP\n");
+ nutscan_avail_snmp = 0;
}
else {
printq(quiet,"Scanning SNMP bus.\n");
@@ -398,6 +399,7 @@ display_help:
if( allow_oldnut && nutscan_avail_nut) {
if( start_ip == NULL ) {
printq(quiet,"No start IP, skipping NUT bus (old connect method)\n");
+ nutscan_avail_nut = 0;
}
else {
printq(quiet,"Scanning NUT bus (old connect method).\n");
--
1.7.10.2
From dc729c5c3da7efb4632f7d9f7a031108540282d9 Mon Sep 17 00:00:00 2001
From: Arnaud Quette <arnaud.quette@free.fr>
Date: Wed, 19 Sep 2012 19:35:45 +0000
Subject: [PATCH] Support for FreeIPMI 1.1.x and 1.2.x (#2)
Prepare for supporting API changes in FreeIPMI 1.1.x and 1.2.x. This 2nd
patch, which completes [[SVN:3675]], addresses FRU API changes, and removes
code redundancy. This code has been tested with FreeIPMI 0.8.12 and
the latest [[FreeIPMI SVN]] trunk r9505 (reported as 1.2.0.beta2 by pkgconfig)
[[SVN:3675]] = 2012-07-16T13:18:18Z!arnaud.quette@free.fr
Fossil-ID: SVN r3733
---
drivers/nut-libfreeipmi.c | 375 ++++++++++++++---------------------------
m4/nut_check_libfreeipmi.m4 | 1 -
tools/nut-scanner/scan_ipmi.c | 103 +++++++----
3 files changed, 192 insertions(+), 287 deletions(-)
diff --git a/drivers/nut-libfreeipmi.c b/drivers/nut-libfreeipmi.c
index 1539e75..dd06369 100644
--- a/drivers/nut-libfreeipmi.c
+++ b/drivers/nut-libfreeipmi.c
@@ -42,10 +42,12 @@
#include <stdlib.h>
#include <string.h>
#include "timehead.h"
+#include "common.h"
#include <freeipmi/freeipmi.h>
#include <ipmi_monitoring.h>
+#if HAVE_FREEIPMI_MONITORING
#include <ipmi_monitoring_bitmasks.h>
-#include "common.h"
+#endif
#include "nut-ipmi.h"
#include "dstate.h"
@@ -57,18 +59,46 @@
/* FreeIPMI contexts and configuration*/
ipmi_ctx_t ipmi_ctx = NULL;
-ipmi_fru_parse_ctx_t fru_parse_ctx = NULL;
ipmi_monitoring_ctx_t mon_ctx = NULL;
struct ipmi_monitoring_ipmi_config ipmi_config;
+
/* SDR management API has changed with 1.1.X and later */
#ifdef HAVE_FREEIPMI_11X_12X
ipmi_sdr_ctx_t sdr_ctx = NULL;
+ ipmi_fru_ctx_t fru_ctx = NULL;
+ #define SDR_PARSE_CTX sdr_ctx
#else
- ipmi_sdr_cache_ctx_t sdr_cache_ctx = NULL;
+ ipmi_sdr_cache_ctx_t sdr_ctx = NULL;
ipmi_sdr_parse_ctx_t sdr_parse_ctx = NULL;
-#ifndef IPMI_SDR_MAX_RECORD_LENGTH
- #define IPMI_SDR_MAX_RECORD_LENGTH IPMI_SDR_CACHE_MAX_SDR_RECORD_LENGTH
-#endif
+ #define SDR_PARSE_CTX sdr_parse_ctx
+ ipmi_fru_parse_ctx_t fru_ctx = NULL;
+ /* Functions remapping */
+ #define ipmi_sdr_ctx_create ipmi_sdr_cache_ctx_create
+ #define ipmi_sdr_ctx_destroy ipmi_sdr_cache_ctx_destroy
+ #define ipmi_sdr_ctx_errnum ipmi_sdr_cache_ctx_errnum
+ #define ipmi_sdr_ctx_errormsg ipmi_sdr_cache_ctx_errormsg
+ #define ipmi_fru_ctx_create ipmi_fru_parse_ctx_create
+ #define ipmi_fru_ctx_destroy ipmi_fru_parse_ctx_destroy
+ #define ipmi_fru_ctx_set_flags ipmi_fru_parse_ctx_set_flags
+ #define ipmi_fru_ctx_strerror ipmi_fru_parse_ctx_strerror
+ #define ipmi_fru_ctx_errnum ipmi_fru_parse_ctx_errnum
+ #define ipmi_fru_open_device_id ipmi_fru_parse_open_device_id
+ #define ipmi_fru_close_device_id ipmi_fru_parse_close_device_id
+ #define ipmi_fru_ctx_errormsg ipmi_fru_parse_ctx_errormsg
+ #define ipmi_fru_read_data_area ipmi_fru_parse_read_data_area
+ #define ipmi_fru_next ipmi_fru_parse_next
+ #define ipmi_fru_type_length_field_to_string ipmi_fru_parse_type_length_field_to_string
+ #define ipmi_fru_multirecord_power_supply_information ipmi_fru_parse_multirecord_power_supply_information
+ #define ipmi_fru_board_info_area ipmi_fru_parse_board_info_area
+ #define ipmi_fru_field_t ipmi_fru_parse_field_t
+ /* Constants */
+ #define IPMI_SDR_MAX_RECORD_LENGTH IPMI_SDR_CACHE_MAX_SDR_RECORD_LENGTH
+ #define IPMI_SDR_ERR_CACHE_READ_CACHE_DOES_NOT_EXIST IPMI_SDR_CACHE_ERR_CACHE_READ_CACHE_DOES_NOT_EXIST
+ #define IPMI_FRU_AREA_SIZE_MAX IPMI_FRU_PARSE_AREA_SIZE_MAX
+ #define IPMI_FRU_FLAGS_SKIP_CHECKSUM_CHECKS IPMI_FRU_PARSE_FLAGS_SKIP_CHECKSUM_CHECKS
+ #define IPMI_FRU_AREA_TYPE_BOARD_INFO_AREA IPMI_FRU_PARSE_AREA_TYPE_BOARD_INFO_AREA
+ #define IPMI_FRU_AREA_TYPE_MULTIRECORD_POWER_SUPPLY_INFORMATION IPMI_FRU_PARSE_AREA_TYPE_MULTIRECORD_POWER_SUPPLY_INFORMATION
+ #define IPMI_FRU_AREA_STRING_MAX IPMI_FRU_PARSE_AREA_STRING_MAX
#endif /* HAVE_FREEIPMI_11X_12X */
/* FIXME: freeipmi auto selects a cache based on the hostname you are
@@ -78,7 +108,7 @@ struct ipmi_monitoring_ipmi_config ipmi_config;
/* Support functions */
static const char* libfreeipmi_getfield (uint8_t language_code,
- ipmi_fru_parse_field_t *field);
+ ipmi_fru_field_t *field);
static void libfreeipmi_cleanup();
@@ -97,7 +127,7 @@ static int libfreeipmi_get_sensors_info (IPMIDevice_t *ipmi_dev);
int nut_ipmi_open(int ipmi_id, IPMIDevice_t *ipmi_dev)
{
int ret = -1;
- uint8_t areabuf[IPMI_FRU_PARSE_AREA_SIZE_MAX+1];
+ uint8_t areabuf[IPMI_FRU_AREA_SIZE_MAX+1];
unsigned int area_type = 0;
unsigned int area_length = 0;
@@ -134,26 +164,26 @@ int nut_ipmi_open(int ipmi_id, IPMIDevice_t *ipmi_dev)
upsdebugx(1, "FreeIPMI initialized...");
/* Parse FRU information */
- if (!(fru_parse_ctx = ipmi_fru_parse_ctx_create (ipmi_ctx)))
+ if (!(fru_ctx = ipmi_fru_ctx_create (ipmi_ctx)))
{
libfreeipmi_cleanup();
- fatal_with_errno(EXIT_FAILURE, "ipmi_fru_parse_ctx_create()");
+ fatal_with_errno(EXIT_FAILURE, "ipmi_fru_ctx_create()");
}
/* lots of motherboards calculate checksums incorrectly */
- if (ipmi_fru_parse_ctx_set_flags (fru_parse_ctx, IPMI_FRU_PARSE_FLAGS_SKIP_CHECKSUM_CHECKS) < 0)
+ if (ipmi_fru_ctx_set_flags (fru_ctx, IPMI_FRU_FLAGS_SKIP_CHECKSUM_CHECKS) < 0)
{
libfreeipmi_cleanup();
- fatalx(EXIT_FAILURE, "ipmi_fru_parse_ctx_set_flags: %s\n",
- ipmi_fru_parse_ctx_strerror (ipmi_fru_parse_ctx_errnum (fru_parse_ctx)));
+ fatalx(EXIT_FAILURE, "ipmi_fru_ctx_set_flags: %s\n",
+ ipmi_fru_ctx_strerror (ipmi_fru_ctx_errnum (fru_ctx)));
}
/* Now open the requested (local) PSU */
- if (ipmi_fru_parse_open_device_id (fru_parse_ctx, ipmi_id) < 0)
+ if (ipmi_fru_open_device_id (fru_ctx, ipmi_id) < 0)
{
libfreeipmi_cleanup();
- fatalx(EXIT_FAILURE, "ipmi_fru_parse_open_device_id: %s\n",
- ipmi_fru_parse_ctx_errormsg (fru_parse_ctx));
+ fatalx(EXIT_FAILURE, "ipmi_fru_open_device_id: %s\n",
+ ipmi_fru_ctx_errormsg (fru_ctx));
}
/* Set IPMI identifier */
@@ -164,19 +194,19 @@ int nut_ipmi_open(int ipmi_id, IPMIDevice_t *ipmi_dev)
/* clear fields */
area_type = 0;
area_length = 0;
- memset (areabuf, '\0', IPMI_FRU_PARSE_AREA_SIZE_MAX + 1);
+ memset (areabuf, '\0', IPMI_FRU_AREA_SIZE_MAX + 1);
/* parse FRU buffer */
- if (ipmi_fru_parse_read_data_area (fru_parse_ctx,
+ if (ipmi_fru_read_data_area (fru_ctx,
&area_type,
&area_length,
areabuf,
- IPMI_FRU_PARSE_AREA_SIZE_MAX) < 0)
+ IPMI_FRU_AREA_SIZE_MAX) < 0)
{
libfreeipmi_cleanup();
fatal_with_errno(EXIT_FAILURE,
- "ipmi_fru_parse_open_device_id: %s\n",
- ipmi_fru_parse_ctx_errormsg (fru_parse_ctx));
+ "ipmi_fru_read_data_area: %s\n",
+ ipmi_fru_ctx_errormsg (fru_ctx));
}
if (area_length)
@@ -184,7 +214,7 @@ int nut_ipmi_open(int ipmi_id, IPMIDevice_t *ipmi_dev)
switch (area_type)
{
/* get generic board information */
- case IPMI_FRU_PARSE_AREA_TYPE_BOARD_INFO_AREA:
+ case IPMI_FRU_AREA_TYPE_BOARD_INFO_AREA:
if(libfreeipmi_get_board_info (areabuf, area_length,
ipmi_dev) < 0)
@@ -193,7 +223,7 @@ int nut_ipmi_open(int ipmi_id, IPMIDevice_t *ipmi_dev)
}
break;
/* get specific PSU information */
- case IPMI_FRU_PARSE_AREA_TYPE_MULTIRECORD_POWER_SUPPLY_INFORMATION:
+ case IPMI_FRU_AREA_TYPE_MULTIRECORD_POWER_SUPPLY_INFORMATION:
if(libfreeipmi_get_psu_info (areabuf, area_length, ipmi_dev) < 0)
{
@@ -205,13 +235,13 @@ int nut_ipmi_open(int ipmi_id, IPMIDevice_t *ipmi_dev)
break;
}
}
- } while ((ret = ipmi_fru_parse_next (fru_parse_ctx)) == 1);
+ } while ((ret = ipmi_fru_next (fru_ctx)) == 1);
/* check for errors */
if (ret < 0) {
libfreeipmi_cleanup();
- fatal_with_errno(EXIT_FAILURE, "ipmi_fru_parse_next: %s",
- ipmi_fru_parse_ctx_errormsg (fru_parse_ctx));
+ fatal_with_errno(EXIT_FAILURE, "ipmi_fru_next: %s",
+ ipmi_fru_ctx_errormsg (fru_ctx));
}
else {
/* Get all related sensors information */
@@ -232,25 +262,25 @@ void nut_ipmi_close(void)
}
static const char* libfreeipmi_getfield (uint8_t language_code,
- ipmi_fru_parse_field_t *field)
+ ipmi_fru_field_t *field)
{
- static char strbuf[IPMI_FRU_PARSE_AREA_STRING_MAX + 1];
- unsigned int strbuflen = IPMI_FRU_PARSE_AREA_STRING_MAX;
+ static char strbuf[IPMI_FRU_AREA_STRING_MAX + 1];
+ unsigned int strbuflen = IPMI_FRU_AREA_STRING_MAX;
if (!field->type_length_field_length)
return NULL;
- memset (strbuf, '\0', IPMI_FRU_PARSE_AREA_STRING_MAX + 1);
+ memset (strbuf, '\0', IPMI_FRU_AREA_STRING_MAX + 1);
- if (ipmi_fru_parse_type_length_field_to_string (fru_parse_ctx,
+ if (ipmi_fru_type_length_field_to_string (fru_ctx,
field->type_length_field,
field->type_length_field_length,
language_code,
strbuf,
&strbuflen) < 0)
{
- upsdebugx (2, "ipmi_fru_parse_type_length_field_to_string: %s",
- ipmi_fru_parse_ctx_errormsg (fru_parse_ctx));
+ upsdebugx (2, "ipmi_fru_type_length_field_to_string: %s",
+ ipmi_fru_ctx_errormsg (fru_ctx));
return NULL;
}
@@ -279,24 +309,20 @@ static float libfreeipmi_get_voltage (uint8_t voltage_code)
static void libfreeipmi_cleanup()
{
/* cleanup */
- if (fru_parse_ctx) {
- ipmi_fru_parse_close_device_id (fru_parse_ctx);
- ipmi_fru_parse_ctx_destroy (fru_parse_ctx);
+ if (fru_ctx) {
+ ipmi_fru_close_device_id (fru_ctx);
+ ipmi_fru_ctx_destroy (fru_ctx);
}
-#ifdef HAVE_FREEIPMI_11X_12X
if (sdr_ctx) {
ipmi_sdr_ctx_destroy (sdr_ctx);
}
-#else /* HAVE_FREEIPMI_11X_12X */
- if (sdr_cache_ctx) {
- ipmi_sdr_cache_ctx_destroy (sdr_cache_ctx);
- }
+#ifndef HAVE_FREEIPMI_11X_12X
if (sdr_parse_ctx) {
ipmi_sdr_parse_ctx_destroy (sdr_parse_ctx);
}
-#endif /* HAVE_FREEIPMI_11X_12X */
+#endif
if (ipmi_ctx) {
ipmi_ctx_close (ipmi_ctx);
@@ -342,7 +368,7 @@ static int libfreeipmi_get_psu_info (const void *areabuf,
upsdebugx(1, "entering libfreeipmi_get_psu_info()");
- if (ipmi_fru_parse_multirecord_power_supply_information (fru_parse_ctx,
+ if (ipmi_fru_multirecord_power_supply_information (fru_ctx,
areabuf,
area_length,
&overall_capacity,
@@ -368,8 +394,8 @@ static int libfreeipmi_get_psu_info (const void *areabuf,
&total_combined_wattage,
&predictive_fail_tachometer_lower_threshold) < 0)
{
- fatalx(EXIT_FAILURE, "ipmi_fru_parse_multirecord_power_supply_information: %s",
- ipmi_fru_parse_ctx_errormsg (fru_parse_ctx));
+ fatalx(EXIT_FAILURE, "ipmi_fru_multirecord_power_supply_information: %s",
+ ipmi_fru_ctx_errormsg (fru_ctx));
}
ipmi_dev->overall_capacity = overall_capacity;
@@ -383,6 +409,8 @@ static int libfreeipmi_get_psu_info (const void *areabuf,
ipmi_dev->voltage = libfreeipmi_get_voltage(voltage_1);
+ upsdebugx(1, "libfreeipmi_get_psu_info() retrieved successfully");
+
return (0);
}
@@ -392,12 +420,12 @@ static int libfreeipmi_get_board_info (const void *areabuf,
{
uint8_t language_code;
uint32_t mfg_date_time;
- ipmi_fru_parse_field_t board_manufacturer;
- ipmi_fru_parse_field_t board_product_name;
- ipmi_fru_parse_field_t board_serial_number;
- ipmi_fru_parse_field_t board_part_number;
- ipmi_fru_parse_field_t board_fru_file_id;
- ipmi_fru_parse_field_t board_custom_fields[IPMI_FRU_CUSTOM_FIELDS];
+ ipmi_fru_field_t board_manufacturer;
+ ipmi_fru_field_t board_product_name;
+ ipmi_fru_field_t board_serial_number;
+ ipmi_fru_field_t board_part_number;
+ ipmi_fru_field_t board_fru_file_id;
+ ipmi_fru_field_t board_custom_fields[IPMI_FRU_CUSTOM_FIELDS];
const char *string = NULL;
time_t timetmp;
struct tm mfg_date_time_tm;
@@ -406,15 +434,15 @@ static int libfreeipmi_get_board_info (const void *areabuf,
upsdebugx(1, "entering libfreeipmi_get_board_info()");
/* clear fields */
- memset (&board_manufacturer, '\0', sizeof (ipmi_fru_parse_field_t));
- memset (&board_product_name, '\0', sizeof (ipmi_fru_parse_field_t));
- memset (&board_serial_number, '\0', sizeof (ipmi_fru_parse_field_t));
- memset (&board_fru_file_id, '\0', sizeof (ipmi_fru_parse_field_t));
+ memset (&board_manufacturer, '\0', sizeof (ipmi_fru_field_t));
+ memset (&board_product_name, '\0', sizeof (ipmi_fru_field_t));
+ memset (&board_serial_number, '\0', sizeof (ipmi_fru_field_t));
+ memset (&board_fru_file_id, '\0', sizeof (ipmi_fru_field_t));
memset (&board_custom_fields[0], '\0',
- sizeof (ipmi_fru_parse_field_t) * IPMI_FRU_CUSTOM_FIELDS);
+ sizeof (ipmi_fru_field_t) * IPMI_FRU_CUSTOM_FIELDS);
/* parse FRU buffer */
- if (ipmi_fru_parse_board_info_area (fru_parse_ctx,
+ if (ipmi_fru_board_info_area (fru_ctx,
areabuf,
area_length,
&language_code,
@@ -428,8 +456,8 @@ static int libfreeipmi_get_board_info (const void *areabuf,
IPMI_FRU_CUSTOM_FIELDS) < 0)
{
libfreeipmi_cleanup();
- fatalx(EXIT_FAILURE, "ipmi_fru_parse_board_info_area: %s",
- ipmi_fru_parse_ctx_errormsg (fru_parse_ctx));
+ fatalx(EXIT_FAILURE, "ipmi_fru_board_info_area: %s",
+ ipmi_fru_ctx_errormsg (fru_ctx));
}
@@ -498,113 +526,64 @@ static int libfreeipmi_get_sensors_info (IPMIDevice_t *ipmi_dev)
ipmi_dev->sensors_count = 0;
memset(ipmi_dev->sensors_id_list, 0, sizeof(ipmi_dev->sensors_id_list));
-#ifdef HAVE_FREEIPMI_11X_12X
if (!(sdr_ctx = ipmi_sdr_ctx_create ()))
{
libfreeipmi_cleanup();
fatal_with_errno(EXIT_FAILURE, "ipmi_sdr_ctx_create()");
}
- if (ipmi_sdr_cache_open (sdr_ctx, ipmi_ctx, CACHE_LOCATION) < 0)
- {
- if (ipmi_sdr_ctx_errnum (sdr_ctx) != IPMI_SDR_ERR_CACHE_READ_CACHE_DOES_NOT_EXIST)
- {
- libfreeipmi_cleanup();
- fatal_with_errno(EXIT_FAILURE, "ipmi_sdr_cache_open: %s",
- ipmi_sdr_ctx_errormsg (sdr_ctx));
- }
- }
-#else /* HAVE_FREEIPMI_11X_12X */
- if (!(sdr_cache_ctx = ipmi_sdr_cache_ctx_create ()))
- {
- libfreeipmi_cleanup();
- fatal_with_errno(EXIT_FAILURE, "ipmi_sdr_cache_ctx_create()");
- }
-
+#ifndef HAVE_FREEIPMI_11X_12X
if (!(sdr_parse_ctx = ipmi_sdr_parse_ctx_create ()))
{
libfreeipmi_cleanup();
fatal_with_errno(EXIT_FAILURE, "ipmi_sdr_parse_ctx_create()");
}
+#endif
- if (ipmi_sdr_cache_open (sdr_cache_ctx, ipmi_ctx, CACHE_LOCATION) < 0)
+ if (ipmi_sdr_cache_open (sdr_ctx, ipmi_ctx, CACHE_LOCATION) < 0)
{
- if (ipmi_sdr_cache_ctx_errnum (sdr_cache_ctx) != IPMI_SDR_CACHE_ERR_CACHE_READ_CACHE_DOES_NOT_EXIST)
+ if (ipmi_sdr_ctx_errnum (sdr_ctx) != IPMI_SDR_ERR_CACHE_READ_CACHE_DOES_NOT_EXIST)
{
libfreeipmi_cleanup();
fatal_with_errno(EXIT_FAILURE, "ipmi_sdr_cache_open: %s",
- ipmi_sdr_cache_ctx_errormsg (sdr_cache_ctx));
+ ipmi_sdr_ctx_errormsg (sdr_ctx));
}
}
-#endif /* HAVE_FREEIPMI_11X_12X */
-#ifdef HAVE_FREEIPMI_11X_12X
if (ipmi_sdr_ctx_errnum (sdr_ctx) == IPMI_SDR_ERR_CACHE_READ_CACHE_DOES_NOT_EXIST)
{
if (ipmi_sdr_cache_create (sdr_ctx,
ipmi_ctx, CACHE_LOCATION,
IPMI_SDR_CACHE_CREATE_FLAGS_DEFAULT,
+#ifndef HAVE_FREEIPMI_11X_12X
+ IPMI_SDR_CACHE_VALIDATION_FLAGS_DEFAULT,
+#endif
NULL, NULL) < 0)
{
libfreeipmi_cleanup();
fatal_with_errno(EXIT_FAILURE, "ipmi_sdr_cache_create: %s",
ipmi_sdr_ctx_errormsg (sdr_ctx));
}
- if (ipmi_sdr_cache_open (sdr_ctx,
- ipmi_ctx, CACHE_LOCATION) < 0)
+ if (ipmi_sdr_cache_open (sdr_ctx, ipmi_ctx, CACHE_LOCATION) < 0)
{
if (ipmi_sdr_ctx_errnum (sdr_ctx) != IPMI_SDR_ERR_CACHE_READ_CACHE_DOES_NOT_EXIST)
{
- libfreeipmi_cleanup();
- fatal_with_errno(EXIT_FAILURE, "ipmi_sdr_cache_open: %s",
- ipmi_sdr_ctx_errormsg (sdr_ctx));
- }
- }
- }
-#else /* HAVE_FREEIPMI_11X_12X */
- if (ipmi_sdr_cache_ctx_errnum (sdr_cache_ctx) == IPMI_SDR_CACHE_ERR_CACHE_READ_CACHE_DOES_NOT_EXIST)
- {
- if (ipmi_sdr_cache_create (sdr_cache_ctx,
- ipmi_ctx, CACHE_LOCATION,
- IPMI_SDR_CACHE_CREATE_FLAGS_DEFAULT,
- IPMI_SDR_CACHE_VALIDATION_FLAGS_DEFAULT,
- NULL, NULL) < 0)
- {
- libfreeipmi_cleanup();
- fatal_with_errno(EXIT_FAILURE, "ipmi_sdr_cache_create: %s",
- ipmi_sdr_cache_ctx_errormsg (sdr_cache_ctx));
- }
- if (ipmi_sdr_cache_open (sdr_cache_ctx,
- ipmi_ctx, CACHE_LOCATION) < 0)
- {
- if (ipmi_sdr_cache_ctx_errnum (sdr_cache_ctx) != IPMI_SDR_CACHE_ERR_CACHE_READ_CACHE_DOES_NOT_EXIST)
- {
- libfreeipmi_cleanup();
- fatal_with_errno(EXIT_FAILURE, "ipmi_sdr_cache_open: %s",
- ipmi_sdr_cache_ctx_errormsg (sdr_cache_ctx));
+ libfreeipmi_cleanup();
+ fatal_with_errno(EXIT_FAILURE, "ipmi_sdr_cache_open: %s",
+ ipmi_sdr_ctx_errormsg (sdr_ctx));
}
}
}
-#endif /* HAVE_FREEIPMI_11X_12X */
-#ifdef HAVE_FREEIPMI_11X_12X
- if (ipmi_sdr_cache_record_count (sdr_ctx, &record_count) < 0) {
+ if (ipmi_sdr_cache_record_count (sdr_ctx, &record_count) < 0) {
fprintf (stderr,
- "ipmi_sdr_cache_record_count: %s",
+ "ipmi_sdr_cache_record_count: %s\n",
ipmi_sdr_ctx_errormsg (sdr_ctx));
goto cleanup;
}
-#else
- if (ipmi_sdr_cache_record_count (sdr_cache_ctx, &record_count) < 0)
- {
- fprintf (stderr,
- "ipmi_sdr_cache_record_count: %s",
- ipmi_sdr_cache_ctx_errormsg (sdr_cache_ctx));
- goto cleanup;
- }
-#endif /* HAVE_FREEIPMI_11X_12X */
-#ifdef HAVE_FREEIPMI_11X_12X
+ upsdebugx(3, "Found %i records in SDR cache", record_count);
+
for (i = 0; i < record_count; i++, ipmi_sdr_cache_next (sdr_ctx))
{
memset (sdr_record, '\0', IPMI_SDR_MAX_RECORD_LENGTH);
@@ -613,50 +592,29 @@ static int libfreeipmi_get_sensors_info (IPMIDevice_t *ipmi_dev)
sdr_record,
IPMI_SDR_MAX_RECORD_LENGTH)) < 0)
{
- fprintf (stderr, "ipmi_sdr_cache_record_read: %s",
+ fprintf (stderr, "ipmi_sdr_cache_record_read: %s\n",
ipmi_sdr_ctx_errormsg (sdr_ctx));
goto cleanup;
}
- if (ipmi_sdr_parse_record_id_and_type (sdr_ctx,
+ if (ipmi_sdr_parse_record_id_and_type (SDR_PARSE_CTX,
sdr_record,
sdr_record_len,
NULL,
&record_type) < 0)
{
- fprintf (stderr, "ipmi_sdr_parse_record_id_and_type: %s",
+ fprintf (stderr, "ipmi_sdr_parse_record_id_and_type: %s\n",
ipmi_sdr_ctx_errormsg (sdr_ctx));
goto cleanup;
}
-#else
- for (i = 0; i < record_count; i++, ipmi_sdr_cache_next (sdr_cache_ctx))
- {
- memset (sdr_record, '\0', IPMI_SDR_MAX_RECORD_LENGTH);
- if ((sdr_record_len = ipmi_sdr_cache_record_read (sdr_cache_ctx,
- sdr_record,
- IPMI_SDR_MAX_RECORD_LENGTH)) < 0)
- {
- fprintf (stderr, "ipmi_sdr_cache_record_read: %s",
- ipmi_sdr_cache_ctx_errormsg (sdr_cache_ctx));
- goto cleanup;
- }
- if (ipmi_sdr_parse_record_id_and_type (sdr_parse_ctx,
- sdr_record,
- sdr_record_len,
- NULL,
- &record_type) < 0)
- {
- fprintf (stderr, "ipmi_sdr_parse_record_id_and_type: %s",
- ipmi_sdr_parse_ctx_errormsg (sdr_parse_ctx));
- goto cleanup;
- }
-#endif /* HAVE_FREEIPMI_11X_12X */
+ upsdebugx (5, "Checking record %i (/%i)", i, record_count);
- if (record_type != IPMI_SDR_FORMAT_FRU_DEVICE_LOCATOR_RECORD)
+ if (record_type != IPMI_SDR_FORMAT_FRU_DEVICE_LOCATOR_RECORD) {
+ upsdebugx(1, "=======> not device locator (%i)!!", record_type);
continue;
+ }
-#ifdef HAVE_FREEIPMI_11X_12X
- if (ipmi_sdr_parse_fru_device_locator_parameters (sdr_ctx,
+ if (ipmi_sdr_parse_fru_device_locator_parameters (SDR_PARSE_CTX,
sdr_record,
sdr_record_len,
NULL,
@@ -666,86 +624,49 @@ static int libfreeipmi_get_sensors_info (IPMIDevice_t *ipmi_dev)
&logical_physical_fru_device,
NULL) < 0)
{
- fprintf (stderr, "ipmi_sdr_parse_fru_device_locator_parameters: %s",
+ fprintf (stderr, "ipmi_sdr_parse_fru_device_locator_parameters: %s\n",
ipmi_sdr_ctx_errormsg (sdr_ctx));
goto cleanup;
}
-#else /* HAVE_FREEIPMI_11X_12X */
- if (ipmi_sdr_parse_fru_device_locator_parameters (sdr_parse_ctx,
- sdr_record,
- sdr_record_len,
- NULL,
- &logical_fru_device_device_slave_address,
- NULL,
- NULL,
- &logical_physical_fru_device,
- NULL) < 0)
- {
- fprintf (stderr, "ipmi_sdr_parse_fru_device_locator_parameters: %s",
- ipmi_sdr_parse_ctx_errormsg (sdr_parse_ctx));
- goto cleanup;
- }
-#endif /* HAVE_FREEIPMI_11X_12X */
+
+ upsdebugx(2, "Checking device %i/%i", logical_physical_fru_device,
+ logical_fru_device_device_slave_address);
if (logical_physical_fru_device
&& logical_fru_device_device_slave_address == ipmi_dev->ipmi_id)
{
found_device_id++;
-#ifdef HAVE_FREEIPMI_11X_12X
- if (ipmi_sdr_parse_fru_entity_id_and_instance (sdr_ctx,
+ if (ipmi_sdr_parse_fru_entity_id_and_instance (SDR_PARSE_CTX,
sdr_record,
sdr_record_len,
&entity_id,
&entity_instance) < 0)
{
fprintf (stderr,
- "ipmi_sdr_parse_fru_entity_id_and_instance: %s",
+ "ipmi_sdr_parse_fru_entity_id_and_instance: %s\n",
ipmi_sdr_ctx_errormsg (sdr_ctx));
goto cleanup;
}
-#else /* HAVE_FREEIPMI_11X_12X */
- if (ipmi_sdr_parse_fru_entity_id_and_instance (sdr_parse_ctx,
- sdr_record,
- sdr_record_len,
- &entity_id,
- &entity_instance) < 0)
- {
- fprintf (stderr,
- "ipmi_sdr_parse_fru_entity_id_and_instance: %s",
- ipmi_sdr_parse_ctx_errormsg (sdr_parse_ctx));
- goto cleanup;
- }
-#endif /* HAVE_FREEIPMI_11X_12X */
break;
}
}
if (!found_device_id)
{
- fprintf (stderr, "Couldn't find device id %d", ipmi_dev->ipmi_id);
+ fprintf (stderr, "Couldn't find device id %d\n", ipmi_dev->ipmi_id);
goto cleanup;
}
else
upsdebugx(1, "Found device id %d", ipmi_dev->ipmi_id);
-#ifdef HAVE_FREEIPMI_11X_12X
if (ipmi_sdr_cache_first (sdr_ctx) < 0)
{
- fprintf (stderr, "ipmi_sdr_cache_first: %s",
+ fprintf (stderr, "ipmi_sdr_cache_first: %s\n",
ipmi_sdr_ctx_errormsg (sdr_ctx));
goto cleanup;
}
-#else /* HAVE_FREEIPMI_11X_12X */
- if (ipmi_sdr_cache_first (sdr_cache_ctx) < 0)
- {
- fprintf (stderr, "ipmi_sdr_cache_first: %s",
- ipmi_sdr_cache_ctx_errormsg (sdr_cache_ctx));
- goto cleanup;
- }
-#endif /* HAVE_FREEIPMI_11X_12X */
-#ifdef HAVE_FREEIPMI_11X_12X
for (i = 0; i < record_count; i++, ipmi_sdr_cache_next (sdr_ctx))
{
/* uint8_t sdr_record[IPMI_SDR_CACHE_MAX_SDR_RECORD_LENGTH];
@@ -757,49 +678,21 @@ static int libfreeipmi_get_sensors_info (IPMIDevice_t *ipmi_dev)
sdr_record,
IPMI_SDR_MAX_RECORD_LENGTH)) < 0)
{
- fprintf (stderr, "ipmi_sdr_cache_record_read: %s",
+ fprintf (stderr, "ipmi_sdr_cache_record_read: %s\n",
ipmi_sdr_ctx_errormsg (sdr_ctx));
goto cleanup;
}
- if (ipmi_sdr_parse_record_id_and_type (sdr_ctx,
+ if (ipmi_sdr_parse_record_id_and_type (SDR_PARSE_CTX,
sdr_record,
sdr_record_len,
&record_id,
&record_type) < 0)
{
- fprintf (stderr, "ipmi_sdr_parse_record_id_and_type: %s",
+ fprintf (stderr, "ipmi_sdr_parse_record_id_and_type: %s\n",
ipmi_sdr_ctx_errormsg (sdr_ctx));
goto cleanup;
}
-#else /* HAVE_FREEIPMI_11X_12X */
- for (i = 0; i < record_count; i++, ipmi_sdr_cache_next (sdr_cache_ctx))
- {
- /* uint8_t sdr_record[IPMI_SDR_CACHE_MAX_SDR_RECORD_LENGTH];
- uint8_t record_type, tmp_entity_id, tmp_entity_instance;
- int sdr_record_len; */
-
- memset (sdr_record, '\0', IPMI_SDR_MAX_RECORD_LENGTH);
- if ((sdr_record_len = ipmi_sdr_cache_record_read (sdr_cache_ctx,
- sdr_record,
- IPMI_SDR_MAX_RECORD_LENGTH)) < 0)
- {
- fprintf (stderr, "ipmi_sdr_cache_record_read: %s",
- ipmi_sdr_cache_ctx_errormsg (sdr_cache_ctx));
- goto cleanup;
- }
-
- if (ipmi_sdr_parse_record_id_and_type (sdr_parse_ctx,
- sdr_record,
- sdr_record_len,
- &record_id,
- &record_type) < 0)
- {
- fprintf (stderr, "ipmi_sdr_parse_record_id_and_type: %s",
- ipmi_sdr_parse_ctx_errormsg (sdr_parse_ctx));
- goto cleanup;
- }
-#endif /* HAVE_FREEIPMI_11X_12X */
upsdebugx (5, "Checking record %i (/%i)", record_id, record_count);
@@ -809,31 +702,17 @@ static int libfreeipmi_get_sensors_info (IPMIDevice_t *ipmi_dev)
continue;
}
-#ifdef HAVE_FREEIPMI_11X_12X
- if (ipmi_sdr_parse_entity_id_instance_type (sdr_ctx,
+ if (ipmi_sdr_parse_entity_id_instance_type (SDR_PARSE_CTX,
sdr_record,
sdr_record_len,
&tmp_entity_id,
&tmp_entity_instance,
NULL) < 0)
{
- fprintf (stderr, "ipmi_sdr_parse_entity_instance_type: %s",
+ fprintf (stderr, "ipmi_sdr_parse_entity_instance_type: %s\n",
ipmi_sdr_ctx_errormsg (sdr_ctx));
goto cleanup;
}
-#else /* HAVE_FREEIPMI_11X_12X */
- if (ipmi_sdr_parse_entity_id_instance_type (sdr_parse_ctx,
- sdr_record,
- sdr_record_len,
- &tmp_entity_id,
- &tmp_entity_instance,
- NULL) < 0)
- {
- fprintf (stderr, "ipmi_sdr_parse_entity_instance_type: %s",
- ipmi_sdr_parse_ctx_errormsg (sdr_parse_ctx));
- goto cleanup;
- }
-#endif /* HAVE_FREEIPMI_11X_12X */
if (tmp_entity_id == entity_id
&& tmp_entity_instance == entity_instance)
@@ -850,15 +729,11 @@ static int libfreeipmi_get_sensors_info (IPMIDevice_t *ipmi_dev)
cleanup:
/* Cleanup */
-#ifdef HAVE_FREEIPMI_11X_12X
if (sdr_ctx) {
ipmi_sdr_ctx_destroy (sdr_ctx);
}
-#else /* HAVE_FREEIPMI_11X_12X */
- if (sdr_cache_ctx) {
- ipmi_sdr_cache_ctx_destroy (sdr_cache_ctx);
- }
+#ifndef HAVE_FREEIPMI_11X_12X
if (sdr_parse_ctx) {
ipmi_sdr_parse_ctx_destroy (sdr_parse_ctx);
}
diff --git a/m4/nut_check_libfreeipmi.m4 b/m4/nut_check_libfreeipmi.m4
index 72e7819..5b2eae9 100644
--- a/m4/nut_check_libfreeipmi.m4
+++ b/m4/nut_check_libfreeipmi.m4
@@ -66,7 +66,6 @@ if test -z "${nut_have_libfreeipmi_seen}"; then
dnl when version cannot be tested (prior to 1.0.5, with no pkg-config)
dnl we have to check for some specific functions
AC_SEARCH_LIBS([ipmi_ctx_find_inband], [freeipmi], [], [nut_have_freeipmi=no])
- AC_SEARCH_LIBS([ipmi_fru_parse_ctx_create], [freeipmi], [], [nut_have_freeipmi=no])
AC_SEARCH_LIBS([ipmi_monitoring_init], [ipmimonitoring], [nut_have_freeipmi_monitoring=yes], [nut_have_freeipmi_monitoring=no])
AC_SEARCH_LIBS([ipmi_monitoring_sensor_read_record_id], [ipmimonitoring], [], [nut_have_freeipmi_monitoring=no])
diff --git a/tools/nut-scanner/scan_ipmi.c b/tools/nut-scanner/scan_ipmi.c
index d650efa..c1ec78a 100644
--- a/tools/nut-scanner/scan_ipmi.c
+++ b/tools/nut-scanner/scan_ipmi.c
@@ -34,24 +34,51 @@ static char * libname = "libfreeipmi";
static lt_dlhandle dl_handle = NULL;
static const char *dl_error = NULL;
-static int (*nut_ipmi_fru_parse_close_device_id) (ipmi_fru_parse_ctx_t ctx);
-static void (*nut_ipmi_fru_parse_ctx_destroy) (ipmi_fru_parse_ctx_t ctx);
#ifdef HAVE_FREEIPMI_11X_12X
-static void (*nut_ipmi_sdr_ctx_destroy) (ipmi_sdr_ctx_t ctx);
+ /* Functions symbols remapping */
+ #define IPMI_FRU_CLOSE_DEVICE_ID "ipmi_fru_close_device_id"
+ #define IPMI_FRU_CTX_DESTROY "ipmi_fru_ctx_destroy"
+ #define IPMI_FRU_CTX_CREATE "ipmi_fru_ctx_create"
+ #define IPMI_FRU_CTX_SET_FLAGS "ipmi_fru_ctx_set_flags"
+ #define IPMI_FRU_OPEN_DEVICE_ID "ipmi_fru_open_device_id"
+ #define IPMI_FRU_CTX_ERRORMSG "ipmi_fru_ctx_errormsg"
+ #define IPMI_FRU_READ_DATA_AREA "ipmi_fru_read_data_area"
+ #define IPMI_FRU_PARSE_NEXT "ipmi_fru_next"
+ typedef ipmi_fru_ctx_t ipmi_fru_parse_ctx_t;
+ typedef ipmi_sdr_ctx_t ipmi_sdr_cache_ctx_t;
+ /* Functions remapping */
+ static void (*nut_ipmi_sdr_ctx_destroy) (ipmi_sdr_ctx_t ctx);
#else /* HAVE_FREEIPMI_11X_12X */
-static void (*nut_ipmi_sdr_cache_ctx_destroy) (ipmi_sdr_cache_ctx_t ctx);
-static void (*nut_ipmi_sdr_parse_ctx_destroy) (ipmi_sdr_parse_ctx_t ctx);
+ #define IPMI_FRU_AREA_SIZE_MAX IPMI_FRU_PARSE_AREA_SIZE_MAX
+ #define IPMI_FRU_FLAGS_SKIP_CHECKSUM_CHECKS IPMI_FRU_PARSE_FLAGS_SKIP_CHECKSUM_CHECKS
+ #define IPMI_FRU_AREA_TYPE_MULTIRECORD_POWER_SUPPLY_INFORMATION IPMI_FRU_PARSE_AREA_TYPE_MULTIRECORD_POWER_SUPPLY_INFORMATION
+ /* Functions symbols remapping */
+ #define IPMI_FRU_CLOSE_DEVICE_ID "ipmi_fru_parse_close_device_id"
+ #define IPMI_FRU_CTX_DESTROY "ipmi_fru_parse_ctx_destroy"
+ #define IPMI_FRU_CTX_CREATE "ipmi_fru_parse_ctx_create"
+ #define IPMI_FRU_CTX_SET_FLAGS "ipmi_fru_parse_ctx_set_flags"
+ #define IPMI_FRU_OPEN_DEVICE_ID "ipmi_fru_parse_open_device_id"
+ #define IPMI_FRU_CTX_ERRORMSG "ipmi_fru_parse_ctx_errormsg"
+ #define IPMI_FRU_READ_DATA_AREA "ipmi_fru_parse_read_data_area"
+ #define IPMI_FRU_PARSE_NEXT "ipmi_fru_parse_next"
+ /* Functions remapping */
+ static void (*nut_ipmi_sdr_cache_ctx_destroy) (ipmi_sdr_cache_ctx_t ctx);
+ static void (*nut_ipmi_sdr_parse_ctx_destroy) (ipmi_sdr_parse_ctx_t ctx);
#endif /* HAVE_FREEIPMI_11X_12X */
-static ipmi_fru_parse_ctx_t (*nut_ipmi_fru_parse_ctx_create) (ipmi_ctx_t ipmi_ctx);
-static int (*nut_ipmi_fru_parse_ctx_set_flags) (ipmi_fru_parse_ctx_t ctx, unsigned int flags);
-static int (*nut_ipmi_fru_parse_open_device_id) (ipmi_fru_parse_ctx_t ctx, uint8_t fru_device_id);
-static char * (*nut_ipmi_fru_parse_ctx_errormsg) (ipmi_fru_parse_ctx_t ctx);
-static int (*nut_ipmi_fru_parse_read_data_area) (ipmi_fru_parse_ctx_t ctx,
+
+
+static int (*nut_ipmi_fru_close_device_id) (ipmi_fru_parse_ctx_t ctx);
+static void (*nut_ipmi_fru_ctx_destroy) (ipmi_fru_parse_ctx_t ctx);
+static ipmi_fru_parse_ctx_t (*nut_ipmi_fru_ctx_create) (ipmi_ctx_t ipmi_ctx);
+static int (*nut_ipmi_fru_ctx_set_flags) (ipmi_fru_parse_ctx_t ctx, unsigned int flags);
+static int (*nut_ipmi_fru_open_device_id) (ipmi_fru_parse_ctx_t ctx, uint8_t fru_device_id);
+static char * (*nut_ipmi_fru_ctx_errormsg) (ipmi_fru_parse_ctx_t ctx);
+static int (*nut_ipmi_fru_read_data_area) (ipmi_fru_parse_ctx_t ctx,
unsigned int *area_type,
unsigned int *area_length,
void *areabuf,
unsigned int areabuflen);
-static int (*nut_ipmi_fru_parse_next) (ipmi_fru_parse_ctx_t ctx);
+static int (*nut_ipmi_fru_next) (ipmi_fru_parse_ctx_t ctx);
static ipmi_ctx_t (*nut_ipmi_ctx_create) (void);
static int (*nut_ipmi_ctx_find_inband) (ipmi_ctx_t ctx,
ipmi_driver_type_t *driver_type,
@@ -92,12 +119,12 @@ int nutscan_load_ipmi_library()
/* Clear any existing error */
lt_dlerror();
- *(void **) (&nut_ipmi_fru_parse_close_device_id) = lt_dlsym(dl_handle, "ipmi_fru_parse_close_device_id");
+ *(void **) (&nut_ipmi_fru_close_device_id) = lt_dlsym(dl_handle, IPMI_FRU_CLOSE_DEVICE_ID);
if ((dl_error = lt_dlerror()) != NULL) {
goto err;
}
- *(void **) (&nut_ipmi_fru_parse_ctx_destroy) = lt_dlsym(dl_handle, "ipmi_fru_parse_ctx_destroy");
+ *(void **) (&nut_ipmi_fru_ctx_destroy) = lt_dlsym(dl_handle, IPMI_FRU_CTX_DESTROY);
if ((dl_error = lt_dlerror()) != NULL) {
goto err;
}
@@ -122,32 +149,32 @@ int nutscan_load_ipmi_library()
}
#endif /* HAVE_FREEIPMI_11X_12X */
- *(void **) (&nut_ipmi_fru_parse_ctx_create) = lt_dlsym(dl_handle, "ipmi_fru_parse_ctx_create");
+ *(void **) (&nut_ipmi_fru_ctx_create) = lt_dlsym(dl_handle, IPMI_FRU_CTX_CREATE);
if ((dl_error = lt_dlerror()) != NULL) {
goto err;
}
- *(void **) (&nut_ipmi_fru_parse_ctx_set_flags) = lt_dlsym(dl_handle, "ipmi_fru_parse_ctx_set_flags");
+ *(void **) (&nut_ipmi_fru_ctx_set_flags) = lt_dlsym(dl_handle, IPMI_FRU_CTX_SET_FLAGS);
if ((dl_error = lt_dlerror()) != NULL) {
goto err;
}
- *(void **) (&nut_ipmi_fru_parse_open_device_id) = lt_dlsym(dl_handle, "ipmi_fru_parse_open_device_id");
+ *(void **) (&nut_ipmi_fru_open_device_id) = lt_dlsym(dl_handle, IPMI_FRU_OPEN_DEVICE_ID);
if ((dl_error = lt_dlerror()) != NULL) {
goto err;
}
- *(void **) (&nut_ipmi_fru_parse_ctx_errormsg) = lt_dlsym(dl_handle, "ipmi_fru_parse_ctx_errormsg");
+ *(void **) (&nut_ipmi_fru_ctx_errormsg) = lt_dlsym(dl_handle, IPMI_FRU_CTX_ERRORMSG);
if ((dl_error = lt_dlerror()) != NULL) {
goto err;
}
- *(void **) (&nut_ipmi_fru_parse_read_data_area) = lt_dlsym(dl_handle, "ipmi_fru_parse_read_data_area");
+ *(void **) (&nut_ipmi_fru_read_data_area) = lt_dlsym(dl_handle, IPMI_FRU_READ_DATA_AREA);
if ((dl_error = lt_dlerror()) != NULL) {
goto err;
}
- *(void **) (&nut_ipmi_fru_parse_next) = lt_dlsym(dl_handle, "ipmi_fru_parse_next");
+ *(void **) (&nut_ipmi_fru_next) = lt_dlsym(dl_handle, IPMI_FRU_PARSE_NEXT);
if ((dl_error = lt_dlerror()) != NULL) {
goto err;
}
@@ -179,7 +206,7 @@ int nutscan_load_ipmi_library()
return 1;
err:
- fprintf(stderr, "Cannot load IPMI library (%s) : %s. IPMI search disabled.\n", libname, dl_error);
+ fprintf(stderr, "Cannot load IPMI library (%s) : %s. IPMI search disabled.\n", libname, dl_error);
dl_handle = (void *)1;
lt_dlexit();
return 0;
@@ -197,8 +224,8 @@ static void nut_freeipmi_cleanup(ipmi_fru_parse_ctx_t fru_parse_ctx,
#endif /* HAVE_FREEIPMI_11X_12X */
{
if (fru_parse_ctx) {
- (*nut_ipmi_fru_parse_close_device_id) (fru_parse_ctx);
- (*nut_ipmi_fru_parse_ctx_destroy) (fru_parse_ctx);
+ (*nut_ipmi_fru_close_device_id) (fru_parse_ctx);
+ (*nut_ipmi_fru_ctx_destroy) (fru_parse_ctx);
}
#ifdef HAVE_FREEIPMI_11X_12X
@@ -226,7 +253,7 @@ int is_ipmi_device_supported(ipmi_ctx_t ipmi_ctx, int ipmi_id)
int ret = -1;
unsigned int area_type = 0;
unsigned int area_length = 0;
- uint8_t areabuf[IPMI_FRU_PARSE_AREA_SIZE_MAX+1];
+ uint8_t areabuf[IPMI_FRU_AREA_SIZE_MAX+1];
ipmi_fru_parse_ctx_t fru_parse_ctx = NULL;
#ifdef HAVE_FREEIPMI_11X_12X
ipmi_sdr_ctx_t sdr_ctx = NULL;
@@ -236,14 +263,14 @@ int is_ipmi_device_supported(ipmi_ctx_t ipmi_ctx, int ipmi_id)
#endif /* HAVE_FREEIPMI_11X_12X */
/* Parse FRU information */
- if (!(fru_parse_ctx = (*nut_ipmi_fru_parse_ctx_create) (ipmi_ctx)))
+ if (!(fru_parse_ctx = (*nut_ipmi_fru_ctx_create) (ipmi_ctx)))
{
fprintf(stderr, "ipmi_fru_parse_ctx_create()\n");
return 0;
}
-
+fprintf(stdout, "There.1\n");
/* lots of motherboards calculate checksums incorrectly */
- if ((*nut_ipmi_fru_parse_ctx_set_flags) (fru_parse_ctx, IPMI_FRU_PARSE_FLAGS_SKIP_CHECKSUM_CHECKS) < 0)
+ if ((*nut_ipmi_fru_ctx_set_flags) (fru_parse_ctx, IPMI_FRU_FLAGS_SKIP_CHECKSUM_CHECKS) < 0)
{
#ifdef HAVE_FREEIPMI_11X_12X
nut_freeipmi_cleanup(fru_parse_ctx, sdr_ctx);
@@ -252,8 +279,8 @@ int is_ipmi_device_supported(ipmi_ctx_t ipmi_ctx, int ipmi_id)
#endif /* HAVE_FREEIPMI_11X_12X */
return 0;
}
-
- if ((*nut_ipmi_fru_parse_open_device_id) (fru_parse_ctx, ipmi_id) < 0)
+fprintf(stdout, "There.2\n");
+ if ((*nut_ipmi_fru_open_device_id) (fru_parse_ctx, ipmi_id) < 0)
{
#ifdef HAVE_FREEIPMI_11X_12X
nut_freeipmi_cleanup(fru_parse_ctx, sdr_ctx);
@@ -265,17 +292,18 @@ int is_ipmi_device_supported(ipmi_ctx_t ipmi_ctx, int ipmi_id)
do
{
+fprintf(stdout, "There.3\n");
/* clear fields */
area_type = 0;
area_length = 0;
- memset (areabuf, '\0', IPMI_FRU_PARSE_AREA_SIZE_MAX + 1);
+ memset (areabuf, '\0', IPMI_FRU_AREA_SIZE_MAX + 1);
/* parse FRU buffer */
- if ((*nut_ipmi_fru_parse_read_data_area) (fru_parse_ctx,
+ if ((*nut_ipmi_fru_read_data_area) (fru_parse_ctx,
&area_type,
&area_length,
areabuf,
- IPMI_FRU_PARSE_AREA_SIZE_MAX) < 0)
+ IPMI_FRU_AREA_SIZE_MAX) < 0)
{
#ifdef HAVE_FREEIPMI_11X_12X
nut_freeipmi_cleanup(fru_parse_ctx, sdr_ctx);
@@ -287,7 +315,7 @@ int is_ipmi_device_supported(ipmi_ctx_t ipmi_ctx, int ipmi_id)
if (area_length)
{
- if (area_type == IPMI_FRU_PARSE_AREA_TYPE_MULTIRECORD_POWER_SUPPLY_INFORMATION)
+ if (area_type == IPMI_FRU_AREA_TYPE_MULTIRECORD_POWER_SUPPLY_INFORMATION)
{
/* Found a POWER_SUPPLY record */
#ifdef HAVE_FREEIPMI_11X_12X
@@ -298,7 +326,7 @@ int is_ipmi_device_supported(ipmi_ctx_t ipmi_ctx, int ipmi_id)
return 1;
}
}
- } while ((ret = (*nut_ipmi_fru_parse_next) (fru_parse_ctx)) == 1);
+ } while ((ret = (*nut_ipmi_fru_next) (fru_parse_ctx)) == 1);
/* No need for further errors checking */
#ifdef HAVE_FREEIPMI_11X_12X
@@ -322,7 +350,7 @@ nutscan_device_t * nutscan_scan_ipmi()
if( !nutscan_avail_ipmi ) {
return NULL;
}
-
+fprintf(stdout, "There1\n");
/* Initialize the FreeIPMI library. */
if (!(ipmi_ctx = (*nut_ipmi_ctx_create) ()))
{
@@ -331,6 +359,7 @@ nutscan_device_t * nutscan_scan_ipmi()
return NULL;
}
+fprintf(stdout, "There2\n");
if ((ret = (*nut_ipmi_ctx_find_inband) (ipmi_ctx,
NULL,
0, /* don't disable auto-probe */
@@ -338,7 +367,7 @@ nutscan_device_t * nutscan_scan_ipmi()
0,
NULL,
0, /* workaround flags, none by default */
- 0 /* flags */
+ IPMI_FLAGS_NONBLOCKING /* flags */
)) < 0)
{
fprintf(stderr, "ipmi_ctx_find_inband: %s\n",
@@ -350,12 +379,14 @@ nutscan_device_t * nutscan_scan_ipmi()
/* No local IPMI device detected */
return NULL;
}
+fprintf(stdout, "There3 (ret = %i)\n", ret);
/* Loop through all possible components */
for (ipmi_id = 0 ; ipmi_id <= IPMI_FRU_DEVICE_ID_MAX ; ipmi_id++) {
-
+fprintf(stdout, "There4\n");
if (is_ipmi_device_supported(ipmi_ctx, ipmi_id)) {
+fprintf(stdout, "There4.%i\n", ipmi_id);
if ( (nut_dev = nutscan_new_device()) == NULL ) {
fprintf(stderr,"Memory allocation error\n");
nutscan_free_device(current_nut_dev);
--
1.7.10.2
From 64add831fe9cd779f125f52782c4c58cbd62d64b Mon Sep 17 00:00:00 2001
From: Arnaud Quette <arnaud.quette@free.fr>
Date: Thu, 4 Oct 2012 22:50:52 +0000
Subject: [PATCH] Support power supplies scan over the network
nut-scanner can now scan for power supplies with IPMI over LAN. This is
currently limited to IPMI 1.5 only
Fossil-ID: SVN r3739
---
docs/man/nut-scanner.txt | 108 +++++++++--------
drivers/nut-ipmipsu.c | 15 ++-
tools/nut-scanner/nut-scan.h | 39 ++++++-
tools/nut-scanner/nut-scanner.c | 74 +++++++++++-
tools/nut-scanner/scan_ipmi.c | 243 ++++++++++++++++++++++++++++++++++-----
5 files changed, 388 insertions(+), 91 deletions(-)
diff --git a/docs/man/nut-scanner.txt b/docs/man/nut-scanner.txt
index 6948449..efe0e58 100644
--- a/docs/man/nut-scanner.txt
+++ b/docs/man/nut-scanner.txt
@@ -36,118 +36,128 @@ DISPLAY OPTIONS
---------------
*-N* | *--disp_nut_conf*::
-
- Display result in the 'ups.conf' format.
+Display result in the 'ups.conf' format.
*-P* | *--disp_parsable*::
-
- Display result in a parsable format.
+Display result in a parsable format.
BUS OPTIONS
-----------
*-C* | *--complete_scan*::
-
- Scan all available communication buses (default behavior)
+Scan all available communication buses (default behavior)
*-U* | *--usb_scan*::
-
- List all NUT-compatible USB devices currently plugged in.
+List all NUT-compatible USB devices currently plugged in.
*-S* | *--snmp_scan*::
-
- Scan SNMP devices. Requires at least a 'start IP', and optionally, an 'end IP'. See specific SNMP OPTIONS for community and security settings.
+Scan SNMP devices. Requires at least a 'start IP', and optionally, an 'end IP'. See specific SNMP OPTIONS for community and security settings.
*-M* | *--xml_scan*::
-
- Scan XML/HTTP devices. Broadcast a network message on the current network interfaces to retrieve XML/HTTP capable devices. No IP required.
+Scan XML/HTTP devices. Broadcast a network message on the current network interfaces to retrieve XML/HTTP capable devices. No IP required.
*-O* | *--oldnut_scan*::
-
- Scan NUT devices (i.e. upsd daemon) on IP ranging from 'start IP' to 'end IP'.
+Scan NUT devices (i.e. upsd daemon) on IP ranging from 'start IP' to 'end IP'.
*-A* | *--avahi_scan*::
-
- Scan NUT servers using Avahi request on the current network interfaces. No IP required.
+Scan NUT servers using Avahi request on the current network interfaces. No IP required.
*-I* | *--ipmi_scan*::
-
- Scan NUT compatible devices available via IPMI on the current host.
+Scan NUT compatible power supplies available via IPMI on the current host, or over the network.
NETWORK OPTIONS
---------------
*-t* | *--timeout* 'timeout'::
-
- Set the network timeout in seconds. Default timeout is 5 seconds.
+Set the network timeout in seconds. Default timeout is 5 seconds.
*-s* | *--start_ip* 'start IP'::
-
- Set the first IP (IPv4 or IPv6) when a range of IP is required (SNMP, old_nut).
+Set the first IP (IPv4 or IPv6) when a range of IP is required (SNMP, old_nut).
*-e* | *--end_ip* 'end IP'::
-
- Set the last IP (IPv4 or IPv6) when a range of IP is required (SNMP, old_nut). If this parameter is omitted, only the 'start IP' is scanned. If 'end IP' is less than 'start IP', both parameters are internally permuted.
+Set the last IP (IPv4 or IPv6) when a range of IP is required (SNMP, old_nut). If this parameter is omitted, only the 'start IP' is scanned. If 'end IP' is less than 'start IP', both parameters are internally permuted.
*-m* | *--mask_cidr* 'IP address/mask'::
-
- Set a range of IP using CIDR notation.
+Set a range of IP using CIDR notation.
NUT DEVICE OPTION
-----------------
*-p* | *--port* 'port number'::
-
- Set the port number of scanned NUT devices (default 3493).
+Set the port number of scanned NUT devices (default 3493).
SNMP V1 OPTION
--------------
*-c* | *--community* 'community'::
-
- Set SNMP v1 community name (default = public).
+Set SNMP v1 community name (default = public).
SNMP V3 OPTIONS
---------------
*-l* | *--secLevel* 'security level'::
-
- Set the 'security level' used for SNMPv3 messages. Allowed values are: noAuthNoPriv, authNoPriv and authPriv.
+Set the 'security level' used for SNMPv3 messages. Allowed values are: noAuthNoPriv, authNoPriv and authPriv.
*-u* | *--secName* 'security name'::
-
- Set the 'security name' used for authenticated SNMPv3 messages. This parameter is mandatory if you set 'security level'.
+Set the 'security name' used for authenticated SNMPv3 messages. This parameter is mandatory if you set 'security level'.
*-w* | *--authProtocol* 'authentication protocol'::
-
- Set the 'authentication protocol' used for authenticated SNMPv3 messages. Allowed values are MD5 or SHA. Default value is MD5.
+Set the 'authentication protocol' used for authenticated SNMPv3 messages. Allowed values are MD5 or SHA. Default value is MD5.
*-W* | *--authPassword* 'authentication pass phrase'::
-
- Set the 'authentication pass phrase' used for authenticated SNMPv3 messages. This parameter is mandatory if you set 'security level' to authNoPriv or authPriv.
+Set the 'authentication pass phrase' used for authenticated SNMPv3 messages. This parameter is mandatory if you set 'security level' to authNoPriv or authPriv.
*-x* | *--privProtocol* 'privacy protocol'::
-
- Set the 'privacy protocol' used for encrypted SNMPv3 messages. Allowed values are DES or AES. Default value is DES.
+Set the 'privacy protocol' used for encrypted SNMPv3 messages. Allowed values are DES or AES. Default value is DES.
*-X* | *--privPassword* 'privacy pass phrase'::
+Set the 'privacy pass phrase' used for encrypted SNMPv3 messages. This parameter is mandatory if you set 'security level' to authPriv.
- Set the 'privacy pass phrase' used for encrypted SNMPv3 messages. This parameter is mandatory if you set 'security level' to authPriv.
+IPMI OPTIONS
+------------
+
+*-b* | *--username* 'username'::
+Set the username used for authenticating IPMI over LAN connections (mandatory for IPMI over LAN. No default).
+
+*-B* | *--password* 'password'::
+Specify the password to use when authenticationg with the remote host (mandatory for IPMI over LAN. No default).
+
+*-d* | *--authType* 'authentication type'::
+Specify the IPMI 1.5 authentication type to use (NONE, STRAIGHT_PASSWORD_KEY, MD2, and MD5) with the remote host (default=MD5).
+This forces connection through the 'lan' IPMI interface , thus in IPMI 1.5 mode.
+
+*-D* | *--cipher_suite_id* 'cipher suite identifier'::
+Specify the IPMI 2.0 cipher suite ID to use. The Cipher Suite ID identifies a set of authentication, integrity, and
+confidentiality algorithms to use for IPMI 2.0 communication. The authentication algorithm identifies the algorithm
+to use for session setup, the integrity algorithm identifies the algorithm to use for session packet signatures, and the
+confidentiality algorithm identifies the algorithm to use for payload encryption (default=3).
++
+The following cipher suite ids are currently supported (Authentication; Integrity; Confidentiality):
+
+- *0*: None; None; None
+- *1*: HMAC-SHA1; None; None
+- *2*: HMAC-SHA1; HMAC-SHA1-96; None
+- *3*: HMAC-SHA1; HMAC-SHA1-96; AES-CBC-128
+- *6*: HMAC-MD5; None; None
+- *7*: HMAC-MD5; HMAC-MD5-128; None
+- *8*: HMAC-MD5; HMAC-MD5-128; AES-CBC-128
+- *11*: HMAC-MD5; MD5-128; None
+- *12*: HMAC-MD5; MD5-128; AES-CBC-128
+- *15*: HMAC-SHA256; None; None
+- *16*: HMAC-SHA256; HMAC_SHA256_128; None
+- *17*: HMAC-SHA256; HMAC_SHA256_128; AES-CBC-128
MISCELLANEOUS OPTIONS
---------------------
*-V* | *--version*::
-
- Display NUT version.
+Display NUT version.
*-a* | *--available*::
-
- Display available bus that can be scanned , depending on how the binary has been compiled. (OLDNUT, USB, SNMP, XML, AVAHI, IPMI).
+Display available bus that can be scanned , depending on how the binary has been compiled. (OLDNUT, USB, SNMP, XML, AVAHI, IPMI).
*-q* | *--quiet*::
-
- Display only scan result. No information on currently scanned bus is displayed.
+Display only scan result. No information on currently scanned bus is displayed.
EXAMPLES
--------
@@ -168,6 +178,10 @@ To scan NUT servers with a timeout of 10 seconds on IP range 192.168.0.0 to 192.
*nut-scanner -O -t 10 -m 192.168.0.0/25*
+To scan for power supplies, through IPMI (1.5 mode) over the network, on address range 192.168.0.0 to 192.168.0.255:
+
+*nut-scanner -I -m 192.168.0.0/24 -b username -B password*
+
SEE ALSO
--------
diff --git a/drivers/nut-ipmipsu.c b/drivers/nut-ipmipsu.c
index b7382a8..2991cfc 100644
--- a/drivers/nut-ipmipsu.c
+++ b/drivers/nut-ipmipsu.c
@@ -27,7 +27,7 @@
#include "nut-ipmi.h"
#define DRIVER_NAME "IPMI PSU driver"
-#define DRIVER_VERSION "0.07"
+#define DRIVER_VERSION "0.30"
/* driver description structure */
upsdrv_info_t upsdrv_info = {
@@ -183,17 +183,20 @@ void upsdrv_makevartable(void)
"Type of the device to match ('psu' for \"Power Supply\")");
addvar(VAR_VALUE, "serial", "Serial number to match a specific device");
- addvar(VAR_VALUE, "fruid", "FRU identifier to match a specific device");
- addvar(VAR_VALUE, "sensorid", "Sensor identifier to match a specific device"); */
+ addvar(VAR_VALUE, "fruid", "FRU identifier to match a specific device"); */
}
void upsdrv_initups(void)
{
upsdebugx(1, "upsdrv_initups...");
- /* port can be expressed using:
- * "id?" for device (FRU) ID 0x?
- * "psu?" for PSU number ?
+ /* port can be expressed in various forms:
+ * - inband:
+ * "id?" for device (FRU) ID 0x?
+ * "psu?" for PSU number ?
+ * - out of band
+ * "id?@host"
+ * "host" => requires serial or ...
*/
if (!strncmp( device_path, "id", 2))
{
diff --git a/tools/nut-scanner/nut-scan.h b/tools/nut-scanner/nut-scan.h
index affcc77..8b9f1ab 100644
--- a/tools/nut-scanner/nut-scan.h
+++ b/tools/nut-scanner/nut-scan.h
@@ -1,6 +1,8 @@
/* nut-scan.h: detect NUT services
*
- * Copyright (C) 2011 - Frederic Bohe <fredericbohe@eaton.com>
+ * Copyright (C)
+ * 2011 - Frederic Bohe <fredericbohe@eaton.com>
+ * 2012 - Arnaud Quette <arnaud.quette@free.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -16,6 +18,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+
#ifndef NUT_SCAN_H
#define NUT_SCAN_H
@@ -23,6 +26,10 @@
#include <nutscan-device.h>
#include <nutscan-ip.h>
+#ifdef WITH_IPMI
+#include <freeipmi/freeipmi.h>
+#endif
+
/* SNMP structure */
typedef struct nutscan_snmp {
char * community;
@@ -36,8 +43,34 @@ typedef struct nutscan_snmp {
void * handle;
} nutscan_snmp_t;
+/* IPMI structure */
+/* Settings for OutofBand (remote) connection */
+typedef struct nutscan_ipmi {
+ char* username; /* IPMI 1.5 and 2.0 */
+ char* password; /* IPMI 1.5 and 2.0 */
+ int authentication_type; /* IPMI 1.5 */
+ int cipher_suite_id; /* IPMI 2.0 */
+ char* K_g_BMC_key; /* IPMI 2.0, optional key for 2 key auth. */
+ int privilege_level; /* for both */
+ unsigned int workaround_flags; /* for both */
+ int ipmi_version; /* IPMI 1.5 or 2.0? */
+} nutscan_ipmi_t;
+
+/* IPMI auth defines, simply using FreeIPMI defines */
+#ifndef IPMI_AUTHENTICATION_TYPE_NONE
+ #define IPMI_AUTHENTICATION_TYPE_NONE 0x00
+ #define IPMI_AUTHENTICATION_TYPE_MD2 0x01
+ #define IPMI_AUTHENTICATION_TYPE_MD5 0x02
+ #define IPMI_AUTHENTICATION_TYPE_STRAIGHT_PASSWORD_KEY 0x04
+ #define IPMI_AUTHENTICATION_TYPE_OEM_PROP 0x05
+ #define IPMI_AUTHENTICATION_TYPE_RMCPPLUS 0x06
+#endif /* IPMI_AUTHENTICATION_TYPE_NONE */
+
+#define IPMI_1_5 1
+#define IPMI_2_0 0
+
/* Scanning */
-nutscan_device_t * nutscan_scan_snmp(const char * start_ip,const char * stop_ip,long usec_timeout, nutscan_snmp_t * sec);
+nutscan_device_t * nutscan_scan_snmp(const char * start_ip, const char * stop_ip, long usec_timeout, nutscan_snmp_t * sec);
nutscan_device_t * nutscan_scan_usb();
@@ -47,7 +80,7 @@ nutscan_device_t * nutscan_scan_nut(const char * startIP, const char * stopIP, c
nutscan_device_t * nutscan_scan_avahi(long usec_timeout);
-nutscan_device_t * nutscan_scan_ipmi(void);
+nutscan_device_t * nutscan_scan_ipmi(const char * startIP, const char * stopIP, nutscan_ipmi_t * sec);
/* Display functions */
void nutscan_display_ups_conf(nutscan_device_t * device);
diff --git a/tools/nut-scanner/nut-scanner.c b/tools/nut-scanner/nut-scanner.c
index 52e0da7..7ca1554 100644
--- a/tools/nut-scanner/nut-scanner.c
+++ b/tools/nut-scanner/nut-scanner.c
@@ -35,7 +35,7 @@
#define ERR_BAD_OPTION (-1)
-const char optstring[] = "?ht:s:e:c:l:u:W:X:w:x:p:CUSMOAm:NPqIVa";
+const char optstring[] = "?ht:s:e:c:l:u:W:X:w:x:p:b:B:d:D:CUSMOAm:NPqIVa";
#ifdef HAVE_GETOPT_LONG
const struct option longopts[] =
@@ -50,6 +50,10 @@ const struct option longopts[] =
{ "privPassword",required_argument,NULL,'X' },
{ "authProtocol",required_argument,NULL,'w' },
{ "privProtocol",required_argument,NULL,'x' },
+ { "username",required_argument,NULL,'b' },
+ { "password",required_argument,NULL,'B' },
+ { "authType",required_argument,NULL,'d' },
+ { "cipher_suite_id",required_argument,NULL,'D' },
{ "port",required_argument,NULL,'p' },
{ "complete_scan",no_argument,NULL,'C' },
{ "usb_scan",no_argument,NULL,'U' },
@@ -110,7 +114,9 @@ static void * run_avahi(void * arg)
}
static void * run_ipmi(void * arg)
{
- dev[TYPE_IPMI] = nutscan_scan_ipmi();
+ nutscan_ipmi_t * sec = (nutscan_ipmi_t *)arg;
+
+ dev[TYPE_IPMI] = nutscan_scan_ipmi(start_ip,end_ip,sec);
return NULL;
}
#endif /* HAVE_PTHREAD */
@@ -133,6 +139,7 @@ static int printq(int quiet,const char *fmt, ...)
int main(int argc, char *argv[])
{
nutscan_snmp_t snmp_sec;
+ nutscan_ipmi_t ipmi_sec;
int opt_ret;
char * cidr = NULL;
int allow_all = 0;
@@ -147,6 +154,12 @@ int main(int argc, char *argv[])
int ret_code = EXIT_SUCCESS;
memset(&snmp_sec, 0, sizeof(snmp_sec));
+ memset(&ipmi_sec, 0, sizeof(ipmi_sec));
+ /* Set the default values for IPMI */
+ ipmi_sec.authentication_type = IPMI_AUTHENTICATION_TYPE_MD5;
+ ipmi_sec.ipmi_version = IPMI_1_5; /* default to IPMI 1.5, if not otherwise specified */
+ ipmi_sec.cipher_suite_id = 3; /* default to HMAC-SHA1; HMAC-SHA1-96; AES-CBC-128 */
+ ipmi_sec.privilege_level = IPMI_PRIVILEGE_LEVEL_ADMIN; /* should be sufficient */
nutscan_init();
@@ -220,6 +233,45 @@ int main(int argc, char *argv[])
}
allow_snmp = 1;
break;
+ case 'b':
+ if(!nutscan_avail_ipmi) {
+ goto display_help;
+ }
+ ipmi_sec.username = strdup(optarg);
+ break;
+ case 'B':
+ if(!nutscan_avail_ipmi) {
+ goto display_help;
+ }
+ ipmi_sec.password = strdup(optarg);
+ break;
+ case 'd':
+ if(!nutscan_avail_ipmi) {
+ goto display_help;
+ }
+ if (!strcmp(optarg, "NONE")) {
+ ipmi_sec.authentication_type = IPMI_AUTHENTICATION_TYPE_NONE;
+ }
+ else if (!strcmp(optarg, "STRAIGHT_PASSWORD_KEY")) {
+ ipmi_sec.authentication_type = IPMI_AUTHENTICATION_TYPE_STRAIGHT_PASSWORD_KEY;
+ }
+ else if (!strcmp(optarg, "MD2")) {
+ ipmi_sec.authentication_type = IPMI_AUTHENTICATION_TYPE_MD2;
+ }
+ else if (!strcmp(optarg, "MD5")) {
+ ipmi_sec.authentication_type = IPMI_AUTHENTICATION_TYPE_MD5;
+ }
+ else {
+ fprintf(stderr,"Unknown authentication type (%s). Defaulting to MD5\n", optarg);
+ }
+ break;
+ case 'D':
+ if(!nutscan_avail_ipmi) {
+ goto display_help;
+ }
+ ipmi_sec.cipher_suite_id = atoi(optarg);
+ /* Force IPMI 2.0! */
+ ipmi_sec.ipmi_version = IPMI_2_0;
case 'p':
port = strdup(optarg);
break;
@@ -307,6 +359,8 @@ display_help:
if( nutscan_avail_ipmi ) {
printf(" -I, --ipmi_scan: Scan IPMI devices.\n");
}
+
+ printf("\nNetwork specific options:\n");
printf(" -t, --timeout <timeout in seconds>: network operation timeout (default %d).\n",DEFAULT_TIMEOUT);
printf(" -s, --start_ip <IP address>: First IP address to scan.\n");
printf(" -e, --end_ip <IP address>: Last IP address to scan.\n");
@@ -325,6 +379,18 @@ display_help:
printf(" -X, --privPassword <privacy pass phrase>: Set the privacy pass phrase used for encrypted SNMPv3 messages (mandatory if you set secLevel to authPriv)\n");
}
+ if( nutscan_avail_ipmi ) {
+ printf("\nIPMI over LAN specific options:\n");
+ printf(" -b, --username <username>: Set the username used for authenticating IPMI over LAN connections (mandatory for IPMI over LAN. No default)\n");
+ /* Specify the username to use when authenticating with the remote host. If not specified, a null (i.e. anonymous) username is assumed. The user must have
+ * at least ADMIN privileges in order for this tool to operate fully. */
+ printf(" -B, --password <password>: Specify the password to use when authenticationg with the remote host (mandatory for IPMI over LAN. No default)\n");
+ /* Specify the password to use when authenticationg with the remote host. If not specified, a null password is assumed. Maximum password length is 16 for IPMI
+ * 1.5 and 20 for IPMI 2.0. */
+ printf(" -d, --authType <authentication type>: Specify the IPMI 1.5 authentication type to use (NONE, STRAIGHT_PASSWORD_KEY, MD2, and MD5) with the remote host (default=MD5)\n");
+ printf(" -D, --cipher_suite_id <cipher suite id>: Specify the IPMI 2.0 cipher suite ID to use, for authentication, integrity, and confidentiality (default=3)\n");
+ }
+
printf("\nNUT specific options:\n");
printf(" -p, --port <port number>: Port number of remote NUT upsd\n");
printf("\ndisplay specific options:\n");
@@ -427,11 +493,11 @@ display_help:
if( allow_ipmi && nutscan_avail_ipmi) {
printq(quiet,"Scanning IPMI bus.\n");
#ifdef HAVE_PTHREAD
- if(pthread_create(&thread[TYPE_IPMI],NULL,run_ipmi,NULL)) {
+ if(pthread_create(&thread[TYPE_IPMI],NULL,run_ipmi,&ipmi_sec)) {
nutscan_avail_ipmi = 0;
}
#else
- dev[TYPE_IPMI] = nutscan_scan_ipmi();
+ dev[TYPE_IPMI] = nutscan_scan_ipmi(start_ip,end_ip,timeout,&ipmi_sec);
#endif /* HAVE_PTHREAD */
}
diff --git a/tools/nut-scanner/scan_ipmi.c b/tools/nut-scanner/scan_ipmi.c
index c1ec78a..0288ad4 100644
--- a/tools/nut-scanner/scan_ipmi.c
+++ b/tools/nut-scanner/scan_ipmi.c
@@ -29,6 +29,11 @@
#define NUT_IPMI_DRV_NAME "nut-ipmipsu"
+/* IPMI defines */
+/* 5 seconds for establishing an IPMI connection */
+#define IPMI_SESSION_TIMEOUT_LENGTH_DEFAULT 5000
+#define IPMI_RETRANSMISSION_TIMEOUT_LENGTH_DEFAULT 250
+
/* dynamic link library stuff */
static char * libname = "libfreeipmi";
static lt_dlhandle dl_handle = NULL;
@@ -88,10 +93,23 @@ static int (*nut_ipmi_ctx_find_inband) (ipmi_ctx_t ctx,
const char *driver_device,
unsigned int workaround_flags,
unsigned int flags);
+static int (*nut_ipmi_ctx_open_outofband) (ipmi_ctx_t ctx,
+ const char *hostname,
+ const char *username,
+ const char *password,
+ uint8_t authentication_type,
+ uint8_t privilege_level,
+ unsigned int session_timeout,
+ unsigned int retransmission_timeout,
+ unsigned int workaround_flags,
+ unsigned int flags);
+static int (*nut_ipmi_ctx_errnum) (ipmi_ctx_t ctx);
static char * (*nut_ipmi_ctx_errormsg) (ipmi_ctx_t ctx);
static int (*nut_ipmi_ctx_close) (ipmi_ctx_t ctx);
static void (*nut_ipmi_ctx_destroy) (ipmi_ctx_t ctx);
+/* Internal functions */
+static nutscan_device_t * nutscan_scan_ipmi_device(const char * IPaddr, nutscan_ipmi_t * sec);
/* Return 0 on error */
int nutscan_load_ipmi_library()
@@ -189,6 +207,16 @@ int nutscan_load_ipmi_library()
goto err;
}
+ *(void **) (&nut_ipmi_ctx_open_outofband) = lt_dlsym(dl_handle, "ipmi_ctx_open_outofband");
+ if ((dl_error = lt_dlerror()) != NULL) {
+ goto err;
+ }
+
+ *(void **) (&nut_ipmi_ctx_errnum) = lt_dlsym(dl_handle, "ipmi_ctx_errnum");
+ if ((dl_error = lt_dlerror()) != NULL) {
+ goto err;
+ }
+
*(void **) (&nut_ipmi_ctx_errormsg) = lt_dlsym(dl_handle, "ipmi_ctx_errormsg");
if ((dl_error = lt_dlerror()) != NULL) {
goto err;
@@ -265,10 +293,10 @@ int is_ipmi_device_supported(ipmi_ctx_t ipmi_ctx, int ipmi_id)
/* Parse FRU information */
if (!(fru_parse_ctx = (*nut_ipmi_fru_ctx_create) (ipmi_ctx)))
{
- fprintf(stderr, "ipmi_fru_parse_ctx_create()\n");
+ fprintf(stderr, "Error with %s(): %s\n", IPMI_FRU_CTX_CREATE, (*nut_ipmi_ctx_errormsg)(ipmi_ctx));
return 0;
}
-fprintf(stdout, "There.1\n");
+
/* lots of motherboards calculate checksums incorrectly */
if ((*nut_ipmi_fru_ctx_set_flags) (fru_parse_ctx, IPMI_FRU_FLAGS_SKIP_CHECKSUM_CHECKS) < 0)
{
@@ -279,7 +307,7 @@ fprintf(stdout, "There.1\n");
#endif /* HAVE_FREEIPMI_11X_12X */
return 0;
}
-fprintf(stdout, "There.2\n");
+
if ((*nut_ipmi_fru_open_device_id) (fru_parse_ctx, ipmi_id) < 0)
{
#ifdef HAVE_FREEIPMI_11X_12X
@@ -292,7 +320,6 @@ fprintf(stdout, "There.2\n");
do
{
-fprintf(stdout, "There.3\n");
/* clear fields */
area_type = 0;
area_length = 0;
@@ -337,20 +364,21 @@ fprintf(stdout, "There.3\n");
return 0;
}
-/* return NULL on error */
-nutscan_device_t * nutscan_scan_ipmi()
+/* Check for IPMI support on a specific (local or remote) system
+ * Return NULL on error, or a valid nutscan_device_t otherwise */
+nutscan_device_t * nutscan_scan_ipmi_device(const char * IPaddr, nutscan_ipmi_t * ipmi_sec)
{
ipmi_ctx_t ipmi_ctx = NULL;
nutscan_device_t * nut_dev = NULL;
nutscan_device_t * current_nut_dev = NULL;
int ret = -1;
int ipmi_id = 0;
- char port_id[10];
+ char port_id[64];
if( !nutscan_avail_ipmi ) {
return NULL;
}
-fprintf(stdout, "There1\n");
+
/* Initialize the FreeIPMI library. */
if (!(ipmi_ctx = (*nut_ipmi_ctx_create) ()))
{
@@ -359,34 +387,138 @@ fprintf(stdout, "There1\n");
return NULL;
}
-fprintf(stdout, "There2\n");
- if ((ret = (*nut_ipmi_ctx_find_inband) (ipmi_ctx,
- NULL,
- 0, /* don't disable auto-probe */
- 0,
- 0,
- NULL,
- 0, /* workaround flags, none by default */
- IPMI_FLAGS_NONBLOCKING /* flags */
- )) < 0)
+ /* Are we scanning locally, or over the network? */
+ if (IPaddr == NULL)
{
- fprintf(stderr, "ipmi_ctx_find_inband: %s\n",
- (*nut_ipmi_ctx_errormsg) (ipmi_ctx));
- return NULL;
+ /* FIXME: we need root right to access local IPMI!
+ if (!ipmi_is_root ()) {
+ fprintf(stderr, "IPMI scan: %s\n", ipmi_ctx_strerror (IPMI_ERR_PERMISSION));
+ } */
+
+ if ((ret = (*nut_ipmi_ctx_find_inband) (ipmi_ctx,
+ NULL,
+ 0, /* don't disable auto-probe */
+ 0,
+ 0,
+ NULL,
+ 0, /* workaround flags, none by default */
+ 0 /* flags */
+ )) < 0)
+ {
+ fprintf(stderr, "ipmi_ctx_find_inband: %s\n",
+ (*nut_ipmi_ctx_errormsg) (ipmi_ctx));
+ return NULL;
+ }
+ if (!ret)
+ {
+ /* No local IPMI device detected */
+ return NULL;
+ }
}
- if (!ret)
- {
- /* No local IPMI device detected */
- return NULL;
+ else {
+
+#if 0
+ if (ipmi_sec->ipmi_version == IPMI_2_0) {
+
+ /* FIXME: need processing?!
+ * int parse_kg (void *out, unsigned int outlen, const char *in)
+ * if ((rv = parse_kg (common_cmd_args_config->k_g, IPMI_MAX_K_G_LENGTH + 1, data->string)) < 0)
+ * {
+ * fprintf (stderr, "Config File Error: k_g input formatted incorrectly\n");
+ * exit (EXIT_FAILURE);
+ * }*/
+ if ((ret = (*nut_ipmi_ctx_open_outofband_2_0) (ipmi_ctx,
+ IPaddr,
+ ipmi_sec->username,
+ ipmi_sec->password,
+ ipmi_sec->K_g_BMC_key,
+??? (ipmi_sec->K_g_BMC_key) ? config->k_g_len : 0,
+ ipmi_sec->privilege_level,
+ ipmi_sec->cipher_suite_id,
+ IPMI_SESSION_TIMEOUT_LENGTH_DEFAULT,
+ IPMI_RETRANSMISSION_TIMEOUT_LENGTH_DEFAULT,
+ ipmi_dev->workaround_flags,
+ flags) < 0)
+ {
+ IPMI_MONITORING_DEBUG (("ipmi_ctx_open_outofband_2_0: %s", ipmi_ctx_errormsg (c->ipmi_ctx)));
+ if (ipmi_ctx_errnum (c->ipmi_ctx) == IPMI_ERR_USERNAME_INVALID)
+ c->errnum = IPMI_MONITORING_ERR_USERNAME_INVALID;
+ else if (ipmi_ctx_errnum (c->ipmi_ctx) == IPMI_ERR_PASSWORD_INVALID)
+ c->errnum = IPMI_MONITORING_ERR_PASSWORD_INVALID;
+ else if (ipmi_ctx_errnum (c->ipmi_ctx) == IPMI_ERR_PRIVILEGE_LEVEL_INSUFFICIENT)
+ c->errnum = IPMI_MONITORING_ERR_PRIVILEGE_LEVEL_INSUFFICIENT;
+ else if (ipmi_ctx_errnum (c->ipmi_ctx) == IPMI_ERR_PRIVILEGE_LEVEL_CANNOT_BE_OBTAINED)
+ c->errnum = IPMI_MONITORING_ERR_PRIVILEGEL_LEVEL_CANNOT_BE_OBTAINED;
+ else if (ipmi_ctx_errnum (c->ipmi_ctx) == IPMI_ERR_K_G_INVALID)
+ c->errnum = IPMI_MONITORING_ERR_K_G_INVALID;
+ else if (ipmi_ctx_errnum (c->ipmi_ctx) == IPMI_ERR_CIPHER_SUITE_ID_UNAVAILABLE)
+ c->errnum = IPMI_MONITORING_ERR_CIPHER_SUITE_ID_UNAVAILABLE;
+ else if (ipmi_ctx_errnum (c->ipmi_ctx) == IPMI_ERR_PASSWORD_VERIFICATION_TIMEOUT)
+ c->errnum = IPMI_MONITORING_ERR_PASSWORD_VERIFICATION_TIMEOUT;
+ else if (ipmi_ctx_errnum (c->ipmi_ctx) == IPMI_ERR_IPMI_2_0_UNAVAILABLE)
+ c->errnum = IPMI_MONITORING_ERR_IPMI_2_0_UNAVAILABLE;
+ else if (ipmi_ctx_errnum (c->ipmi_ctx) == IPMI_ERR_CONNECTION_TIMEOUT)
+ c->errnum = IPMI_MONITORING_ERR_CONNECTION_TIMEOUT;
+ else if (ipmi_ctx_errnum (c->ipmi_ctx) == IPMI_ERR_SESSION_TIMEOUT)
+ c->errnum = IPMI_MONITORING_ERR_SESSION_TIMEOUT;
+ else if (ipmi_ctx_errnum (c->ipmi_ctx) == IPMI_ERR_BAD_COMPLETION_CODE
+ || ipmi_ctx_errnum (c->ipmi_ctx) == IPMI_ERR_IPMI_ERROR)
+ c->errnum = IPMI_MONITORING_ERR_IPMI_ERROR;
+ else if (ipmi_ctx_errnum (c->ipmi_ctx) == IPMI_ERR_BMC_BUSY)
+ c->errnum = IPMI_MONITORING_ERR_BMC_BUSY;
+ else if (ipmi_ctx_errnum (c->ipmi_ctx) == IPMI_ERR_OUT_OF_MEMORY)
+ c->errnum = IPMI_MONITORING_ERR_OUT_OF_MEMORY;
+ else if (ipmi_ctx_errnum (c->ipmi_ctx) == IPMI_ERR_HOSTNAME_INVALID)
+ c->errnum = IPMI_MONITORING_ERR_HOSTNAME_INVALID;
+ else if (ipmi_ctx_errnum (c->ipmi_ctx) == IPMI_ERR_PARAMETERS)
+ c->errnum = IPMI_MONITORING_ERR_PARAMETERS;
+ else if (ipmi_ctx_errnum (c->ipmi_ctx) == IPMI_ERR_SYSTEM_ERROR)
+ c->errnum = IPMI_MONITORING_ERR_SYSTEM_ERROR;
+ else
+ c->errnum = IPMI_MONITORING_ERR_INTERNAL_ERROR;
+ return (-1);
+ }
+ }
+ else { /* Not IPMI 2.0 */
+
+#endif /* 0 */
+
+ /* Fall back to IPMI 1.5 */
+ if ((ret = (*nut_ipmi_ctx_open_outofband) (ipmi_ctx,
+ IPaddr,
+ ipmi_sec->username,
+ ipmi_sec->password,
+ ipmi_sec->authentication_type,
+ ipmi_sec->privilege_level,
+ IPMI_SESSION_TIMEOUT_LENGTH_DEFAULT,
+ IPMI_RETRANSMISSION_TIMEOUT_LENGTH_DEFAULT,
+ ipmi_sec->workaround_flags,
+ IPMI_FLAGS_DEFAULT
+ )) < 0)
+ {
+ /* No IPMI device detected on this host!
+ if ((*nut_ipmi_ctx_errnum) (ipmi_ctx) == IPMI_ERR_USERNAME_INVALID
+ || (*nut_ipmi_ctx_errnum) (ipmi_ctx) == IPMI_ERR_PASSWORD_INVALID
+ || (*nut_ipmi_ctx_errnum) (ipmi_ctx) == IPMI_ERR_PRIVILEGE_LEVEL_INSUFFICIENT
+ || (*nut_ipmi_ctx_errnum) (ipmi_ctx) == IPMI_ERR_PRIVILEGE_LEVEL_CANNOT_BE_OBTAINED
+ || (*nut_ipmi_ctx_errnum) (ipmi_ctx) == IPMI_ERR_AUTHENTICATION_TYPE_UNAVAILABLE
+ || (*nut_ipmi_ctx_errnum) (ipmi_ctx) == IPMI_ERR_PASSWORD_VERIFICATION_TIMEOUT
+ || (*nut_ipmi_ctx_errnum) (ipmi_ctx) == IPMI_ERR_HOSTNAME_INVALID
+ || (*nut_ipmi_ctx_errnum) (ipmi_ctx) == IPMI_ERR_CONNECTION_TIMEOUT) { */
+
+ /* FIXME: don't log timeout errors */
+ fprintf(stderr, "nut_ipmi_ctx_open_outofband: %s\n",
+ (*nut_ipmi_ctx_errormsg) (ipmi_ctx));
+ return NULL;
+ /*}*/
+ }
}
-fprintf(stdout, "There3 (ret = %i)\n", ret);
/* Loop through all possible components */
for (ipmi_id = 0 ; ipmi_id <= IPMI_FRU_DEVICE_ID_MAX ; ipmi_id++) {
-fprintf(stdout, "There4\n");
+
if (is_ipmi_device_supported(ipmi_ctx, ipmi_id)) {
-fprintf(stdout, "There4.%i\n", ipmi_id);
if ( (nut_dev = nutscan_new_device()) == NULL ) {
fprintf(stderr,"Memory allocation error\n");
nutscan_free_device(current_nut_dev);
@@ -396,9 +528,17 @@ fprintf(stdout, "There4.%i\n", ipmi_id);
/* Fill the device structure (sufficient with driver and port) */
nut_dev->type = TYPE_IPMI;
nut_dev->driver = strdup(NUT_IPMI_DRV_NAME);
- sprintf(port_id, "id%x", ipmi_id);
+ if (IPaddr == NULL) {
+ sprintf(port_id, "id%x", ipmi_id);
+ }
+ else {
+ /* FIXME: also check against "localhost" and its IPv{4,6} */
+ sprintf(port_id, "id%x@%s", ipmi_id, IPaddr);
+ }
nut_dev->port = strdup(port_id);
-
+ /* FIXME: also dump device.serial?
+ * using drivers/libfreeipmi_get_board_info() */
+
current_nut_dev = nutscan_add_device_to_device(
current_nut_dev,
nut_dev);
@@ -415,9 +555,50 @@ fprintf(stdout, "There4.%i\n", ipmi_id);
return current_nut_dev;
}
+
+/* General IPMI scan entry point: scan 1 to n devices, local or remote,
+ * for IPMI support
+ * Return NULL on error, or a valid nutscan_device_t otherwise */
+nutscan_device_t * nutscan_scan_ipmi(const char * start_ip, const char * stop_ip, nutscan_ipmi_t * sec)
+{
+ nutscan_ip_iter_t ip;
+ char * ip_str = NULL;
+ nutscan_ipmi_t * tmp_sec;
+ nutscan_device_t * nut_dev = NULL;
+ nutscan_device_t * current_nut_dev = NULL;
+
+ if( !nutscan_avail_ipmi ) {
+ return NULL;
+ }
+
+
+ /* Are we scanning locally, or through the network? */
+ if (start_ip == NULL)
+ {
+ /* Local PSU scan */
+ current_nut_dev = nutscan_scan_ipmi_device(NULL, NULL);
+ }
+ else {
+ ip_str = nutscan_ip_iter_init(&ip, start_ip, stop_ip);
+
+ while(ip_str != NULL) {
+ tmp_sec = malloc(sizeof(nutscan_ipmi_t));
+ memcpy(tmp_sec, sec, sizeof(nutscan_ipmi_t));
+
+ if ((current_nut_dev = nutscan_scan_ipmi_device(ip_str, tmp_sec)) != NULL) {
+ /* Store the positive result */
+ current_nut_dev = nutscan_add_device_to_device(current_nut_dev, nut_dev);
+ }
+ /* Prepare the next iteration */
+ ip_str = nutscan_ip_iter_inc(&ip);
+ };
+ }
+
+ return current_nut_dev;
+}
#else /* WITH_IPMI */
/* stub function */
-nutscan_device_t * nutscan_scan_ipmi()
+nutscan_device_t * nutscan_scan_ipmi(const char * startIP, const char * stopIP, nutscan_ipmi_t * sec)
{
return NULL;
}
--
1.7.10.2
From 3d0002653a506f2acb24be2201724e7b785de784 Mon Sep 17 00:00:00 2001
From: Arnaud Quette <arnaud.quette@free.fr>
Date: Fri, 5 Oct 2012 10:27:55 +0000
Subject: [PATCH] Fix compilation error
Define IPMI_PRIVILEGE_LEVEL_ADMIN value, in case FreeIPMI is not
available
Fossil-ID: SVN r3741
---
tools/nut-scanner/nut-scan.h | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/tools/nut-scanner/nut-scan.h b/tools/nut-scanner/nut-scan.h
index 8b9f1ab..b853d96 100644
--- a/tools/nut-scanner/nut-scan.h
+++ b/tools/nut-scanner/nut-scan.h
@@ -64,7 +64,10 @@ typedef struct nutscan_ipmi {
#define IPMI_AUTHENTICATION_TYPE_STRAIGHT_PASSWORD_KEY 0x04
#define IPMI_AUTHENTICATION_TYPE_OEM_PROP 0x05
#define IPMI_AUTHENTICATION_TYPE_RMCPPLUS 0x06
-#endif /* IPMI_AUTHENTICATION_TYPE_NONE */
+#endif
+#ifndef IPMI_PRIVILEGE_LEVEL_ADMIN
+ #define IPMI_PRIVILEGE_LEVEL_ADMIN 0x04
+#endif
#define IPMI_1_5 1
#define IPMI_2_0 0
--
1.7.10.2
From 605ef0a46fbb8519b849683028f7e6cf35eb2fdd Mon Sep 17 00:00:00 2001
From: Arnaud Quette <arnaud.quette@free.fr>
Date: Thu, 11 Apr 2013 23:15:51 +0200
Subject: [PATCH] Set USB timeout to 5 seconds
Set the low level USB timeout back to the standard
5 seconds. This was set to 4 seconds, for performance
reasons, but is now causing issues with some devices
(reported by Stefan "stevenbg", GitHub issue #23)
---
drivers/libusb.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/drivers/libusb.c b/drivers/libusb.c
index 50bfc7f..234b9f1 100644
--- a/drivers/libusb.c
+++ b/drivers/libusb.c
@@ -33,12 +33,11 @@
#include "usb-common.h"
#include "libusb.h"
-/* USB standard state 5000, but we've decreased it to
- * improve reactivity */
-#define USB_TIMEOUT 4000
+/* USB standard timeout */
+#define USB_TIMEOUT 5000
#define USB_DRIVER_NAME "USB communication driver"
-#define USB_DRIVER_VERSION "0.31"
+#define USB_DRIVER_VERSION "0.32"
/* driver description structure */
upsdrv_info_t comm_upsdrv_info = {
--
1.7.10.2