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
						
					
					
				
			
		
		
	
	
							1931 lines
						
					
					
						
							70 KiB
						
					
					
				| From 6df63fe455745d8d74010d9ad4f85a30f40b5c08 Mon Sep 17 00:00:00 2001 | |
| From: Frederic Bohe <[email protected]> | |
| 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 <[email protected]> | |
| 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:[email protected] | |
|  | |
| 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 <[email protected]> | |
| 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 <[email protected]> | |
| + *  Copyright (C) | |
| + *    2011 - Frederic Bohe <[email protected]> | |
| + *    2012 - Arnaud Quette <[email protected]> | |
|   * | |
|   *  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 <[email protected]> | |
| 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 <[email protected]> | |
| 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 | |
| 
 | |
| 
 |