OpenSDE Packages Database (without history before r20070)
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

  1. From 6df63fe455745d8d74010d9ad4f85a30f40b5c08 Mon Sep 17 00:00:00 2001
  2. From: Frederic Bohe <fbohe-guest@alioth.debian.org>
  3. Date: Mon, 10 Sep 2012 13:28:35 +0000
  4. Subject: [PATCH] [nut-scanner] Fix a crash when no start IP is provided.
  5. Fossil-ID: SVN r3722
  6. ---
  7. tools/nut-scanner/nut-scanner.c | 2 ++
  8. 1 file changed, 2 insertions(+)
  9. diff --git a/tools/nut-scanner/nut-scanner.c b/tools/nut-scanner/nut-scanner.c
  10. index db582be..52e0da7 100644
  11. --- a/tools/nut-scanner/nut-scanner.c
  12. +++ b/tools/nut-scanner/nut-scanner.c
  13. @@ -371,6 +371,7 @@ display_help:
  14. if( allow_snmp && nutscan_avail_snmp ) {
  15. if( start_ip == NULL ) {
  16. printq(quiet,"No start IP, skipping SNMP\n");
  17. + nutscan_avail_snmp = 0;
  18. }
  19. else {
  20. printq(quiet,"Scanning SNMP bus.\n");
  21. @@ -398,6 +399,7 @@ display_help:
  22. if( allow_oldnut && nutscan_avail_nut) {
  23. if( start_ip == NULL ) {
  24. printq(quiet,"No start IP, skipping NUT bus (old connect method)\n");
  25. + nutscan_avail_nut = 0;
  26. }
  27. else {
  28. printq(quiet,"Scanning NUT bus (old connect method).\n");
  29. --
  30. 1.7.10.2
  31. From dc729c5c3da7efb4632f7d9f7a031108540282d9 Mon Sep 17 00:00:00 2001
  32. From: Arnaud Quette <arnaud.quette@free.fr>
  33. Date: Wed, 19 Sep 2012 19:35:45 +0000
  34. Subject: [PATCH] Support for FreeIPMI 1.1.x and 1.2.x (#2)
  35. Prepare for supporting API changes in FreeIPMI 1.1.x and 1.2.x. This 2nd
  36. patch, which completes [[SVN:3675]], addresses FRU API changes, and removes
  37. code redundancy. This code has been tested with FreeIPMI 0.8.12 and
  38. the latest [[FreeIPMI SVN]] trunk r9505 (reported as 1.2.0.beta2 by pkgconfig)
  39. [[SVN:3675]] = 2012-07-16T13:18:18Z!arnaud.quette@free.fr
  40. Fossil-ID: SVN r3733
  41. ---
  42. drivers/nut-libfreeipmi.c | 375 ++++++++++++++---------------------------
  43. m4/nut_check_libfreeipmi.m4 | 1 -
  44. tools/nut-scanner/scan_ipmi.c | 103 +++++++----
  45. 3 files changed, 192 insertions(+), 287 deletions(-)
  46. diff --git a/drivers/nut-libfreeipmi.c b/drivers/nut-libfreeipmi.c
  47. index 1539e75..dd06369 100644
  48. --- a/drivers/nut-libfreeipmi.c
  49. +++ b/drivers/nut-libfreeipmi.c
  50. @@ -42,10 +42,12 @@
  51. #include <stdlib.h>
  52. #include <string.h>
  53. #include "timehead.h"
  54. +#include "common.h"
  55. #include <freeipmi/freeipmi.h>
  56. #include <ipmi_monitoring.h>
  57. +#if HAVE_FREEIPMI_MONITORING
  58. #include <ipmi_monitoring_bitmasks.h>
  59. -#include "common.h"
  60. +#endif
  61. #include "nut-ipmi.h"
  62. #include "dstate.h"
  63. @@ -57,18 +59,46 @@
  64. /* FreeIPMI contexts and configuration*/
  65. ipmi_ctx_t ipmi_ctx = NULL;
  66. -ipmi_fru_parse_ctx_t fru_parse_ctx = NULL;
  67. ipmi_monitoring_ctx_t mon_ctx = NULL;
  68. struct ipmi_monitoring_ipmi_config ipmi_config;
  69. +
  70. /* SDR management API has changed with 1.1.X and later */
  71. #ifdef HAVE_FREEIPMI_11X_12X
  72. ipmi_sdr_ctx_t sdr_ctx = NULL;
  73. + ipmi_fru_ctx_t fru_ctx = NULL;
  74. + #define SDR_PARSE_CTX sdr_ctx
  75. #else
  76. - ipmi_sdr_cache_ctx_t sdr_cache_ctx = NULL;
  77. + ipmi_sdr_cache_ctx_t sdr_ctx = NULL;
  78. ipmi_sdr_parse_ctx_t sdr_parse_ctx = NULL;
  79. -#ifndef IPMI_SDR_MAX_RECORD_LENGTH
  80. - #define IPMI_SDR_MAX_RECORD_LENGTH IPMI_SDR_CACHE_MAX_SDR_RECORD_LENGTH
  81. -#endif
  82. + #define SDR_PARSE_CTX sdr_parse_ctx
  83. + ipmi_fru_parse_ctx_t fru_ctx = NULL;
  84. + /* Functions remapping */
  85. + #define ipmi_sdr_ctx_create ipmi_sdr_cache_ctx_create
  86. + #define ipmi_sdr_ctx_destroy ipmi_sdr_cache_ctx_destroy
  87. + #define ipmi_sdr_ctx_errnum ipmi_sdr_cache_ctx_errnum
  88. + #define ipmi_sdr_ctx_errormsg ipmi_sdr_cache_ctx_errormsg
  89. + #define ipmi_fru_ctx_create ipmi_fru_parse_ctx_create
  90. + #define ipmi_fru_ctx_destroy ipmi_fru_parse_ctx_destroy
  91. + #define ipmi_fru_ctx_set_flags ipmi_fru_parse_ctx_set_flags
  92. + #define ipmi_fru_ctx_strerror ipmi_fru_parse_ctx_strerror
  93. + #define ipmi_fru_ctx_errnum ipmi_fru_parse_ctx_errnum
  94. + #define ipmi_fru_open_device_id ipmi_fru_parse_open_device_id
  95. + #define ipmi_fru_close_device_id ipmi_fru_parse_close_device_id
  96. + #define ipmi_fru_ctx_errormsg ipmi_fru_parse_ctx_errormsg
  97. + #define ipmi_fru_read_data_area ipmi_fru_parse_read_data_area
  98. + #define ipmi_fru_next ipmi_fru_parse_next
  99. + #define ipmi_fru_type_length_field_to_string ipmi_fru_parse_type_length_field_to_string
  100. + #define ipmi_fru_multirecord_power_supply_information ipmi_fru_parse_multirecord_power_supply_information
  101. + #define ipmi_fru_board_info_area ipmi_fru_parse_board_info_area
  102. + #define ipmi_fru_field_t ipmi_fru_parse_field_t
  103. + /* Constants */
  104. + #define IPMI_SDR_MAX_RECORD_LENGTH IPMI_SDR_CACHE_MAX_SDR_RECORD_LENGTH
  105. + #define IPMI_SDR_ERR_CACHE_READ_CACHE_DOES_NOT_EXIST IPMI_SDR_CACHE_ERR_CACHE_READ_CACHE_DOES_NOT_EXIST
  106. + #define IPMI_FRU_AREA_SIZE_MAX IPMI_FRU_PARSE_AREA_SIZE_MAX
  107. + #define IPMI_FRU_FLAGS_SKIP_CHECKSUM_CHECKS IPMI_FRU_PARSE_FLAGS_SKIP_CHECKSUM_CHECKS
  108. + #define IPMI_FRU_AREA_TYPE_BOARD_INFO_AREA IPMI_FRU_PARSE_AREA_TYPE_BOARD_INFO_AREA
  109. + #define IPMI_FRU_AREA_TYPE_MULTIRECORD_POWER_SUPPLY_INFORMATION IPMI_FRU_PARSE_AREA_TYPE_MULTIRECORD_POWER_SUPPLY_INFORMATION
  110. + #define IPMI_FRU_AREA_STRING_MAX IPMI_FRU_PARSE_AREA_STRING_MAX
  111. #endif /* HAVE_FREEIPMI_11X_12X */
  112. /* FIXME: freeipmi auto selects a cache based on the hostname you are
  113. @@ -78,7 +108,7 @@ struct ipmi_monitoring_ipmi_config ipmi_config;
  114. /* Support functions */
  115. static const char* libfreeipmi_getfield (uint8_t language_code,
  116. - ipmi_fru_parse_field_t *field);
  117. + ipmi_fru_field_t *field);
  118. static void libfreeipmi_cleanup();
  119. @@ -97,7 +127,7 @@ static int libfreeipmi_get_sensors_info (IPMIDevice_t *ipmi_dev);
  120. int nut_ipmi_open(int ipmi_id, IPMIDevice_t *ipmi_dev)
  121. {
  122. int ret = -1;
  123. - uint8_t areabuf[IPMI_FRU_PARSE_AREA_SIZE_MAX+1];
  124. + uint8_t areabuf[IPMI_FRU_AREA_SIZE_MAX+1];
  125. unsigned int area_type = 0;
  126. unsigned int area_length = 0;
  127. @@ -134,26 +164,26 @@ int nut_ipmi_open(int ipmi_id, IPMIDevice_t *ipmi_dev)
  128. upsdebugx(1, "FreeIPMI initialized...");
  129. /* Parse FRU information */
  130. - if (!(fru_parse_ctx = ipmi_fru_parse_ctx_create (ipmi_ctx)))
  131. + if (!(fru_ctx = ipmi_fru_ctx_create (ipmi_ctx)))
  132. {
  133. libfreeipmi_cleanup();
  134. - fatal_with_errno(EXIT_FAILURE, "ipmi_fru_parse_ctx_create()");
  135. + fatal_with_errno(EXIT_FAILURE, "ipmi_fru_ctx_create()");
  136. }
  137. /* lots of motherboards calculate checksums incorrectly */
  138. - if (ipmi_fru_parse_ctx_set_flags (fru_parse_ctx, IPMI_FRU_PARSE_FLAGS_SKIP_CHECKSUM_CHECKS) < 0)
  139. + if (ipmi_fru_ctx_set_flags (fru_ctx, IPMI_FRU_FLAGS_SKIP_CHECKSUM_CHECKS) < 0)
  140. {
  141. libfreeipmi_cleanup();
  142. - fatalx(EXIT_FAILURE, "ipmi_fru_parse_ctx_set_flags: %s\n",
  143. - ipmi_fru_parse_ctx_strerror (ipmi_fru_parse_ctx_errnum (fru_parse_ctx)));
  144. + fatalx(EXIT_FAILURE, "ipmi_fru_ctx_set_flags: %s\n",
  145. + ipmi_fru_ctx_strerror (ipmi_fru_ctx_errnum (fru_ctx)));
  146. }
  147. /* Now open the requested (local) PSU */
  148. - if (ipmi_fru_parse_open_device_id (fru_parse_ctx, ipmi_id) < 0)
  149. + if (ipmi_fru_open_device_id (fru_ctx, ipmi_id) < 0)
  150. {
  151. libfreeipmi_cleanup();
  152. - fatalx(EXIT_FAILURE, "ipmi_fru_parse_open_device_id: %s\n",
  153. - ipmi_fru_parse_ctx_errormsg (fru_parse_ctx));
  154. + fatalx(EXIT_FAILURE, "ipmi_fru_open_device_id: %s\n",
  155. + ipmi_fru_ctx_errormsg (fru_ctx));
  156. }
  157. /* Set IPMI identifier */
  158. @@ -164,19 +194,19 @@ int nut_ipmi_open(int ipmi_id, IPMIDevice_t *ipmi_dev)
  159. /* clear fields */
  160. area_type = 0;
  161. area_length = 0;
  162. - memset (areabuf, '\0', IPMI_FRU_PARSE_AREA_SIZE_MAX + 1);
  163. + memset (areabuf, '\0', IPMI_FRU_AREA_SIZE_MAX + 1);
  164. /* parse FRU buffer */
  165. - if (ipmi_fru_parse_read_data_area (fru_parse_ctx,
  166. + if (ipmi_fru_read_data_area (fru_ctx,
  167. &area_type,
  168. &area_length,
  169. areabuf,
  170. - IPMI_FRU_PARSE_AREA_SIZE_MAX) < 0)
  171. + IPMI_FRU_AREA_SIZE_MAX) < 0)
  172. {
  173. libfreeipmi_cleanup();
  174. fatal_with_errno(EXIT_FAILURE,
  175. - "ipmi_fru_parse_open_device_id: %s\n",
  176. - ipmi_fru_parse_ctx_errormsg (fru_parse_ctx));
  177. + "ipmi_fru_read_data_area: %s\n",
  178. + ipmi_fru_ctx_errormsg (fru_ctx));
  179. }
  180. if (area_length)
  181. @@ -184,7 +214,7 @@ int nut_ipmi_open(int ipmi_id, IPMIDevice_t *ipmi_dev)
  182. switch (area_type)
  183. {
  184. /* get generic board information */
  185. - case IPMI_FRU_PARSE_AREA_TYPE_BOARD_INFO_AREA:
  186. + case IPMI_FRU_AREA_TYPE_BOARD_INFO_AREA:
  187. if(libfreeipmi_get_board_info (areabuf, area_length,
  188. ipmi_dev) < 0)
  189. @@ -193,7 +223,7 @@ int nut_ipmi_open(int ipmi_id, IPMIDevice_t *ipmi_dev)
  190. }
  191. break;
  192. /* get specific PSU information */
  193. - case IPMI_FRU_PARSE_AREA_TYPE_MULTIRECORD_POWER_SUPPLY_INFORMATION:
  194. + case IPMI_FRU_AREA_TYPE_MULTIRECORD_POWER_SUPPLY_INFORMATION:
  195. if(libfreeipmi_get_psu_info (areabuf, area_length, ipmi_dev) < 0)
  196. {
  197. @@ -205,13 +235,13 @@ int nut_ipmi_open(int ipmi_id, IPMIDevice_t *ipmi_dev)
  198. break;
  199. }
  200. }
  201. - } while ((ret = ipmi_fru_parse_next (fru_parse_ctx)) == 1);
  202. + } while ((ret = ipmi_fru_next (fru_ctx)) == 1);
  203. /* check for errors */
  204. if (ret < 0) {
  205. libfreeipmi_cleanup();
  206. - fatal_with_errno(EXIT_FAILURE, "ipmi_fru_parse_next: %s",
  207. - ipmi_fru_parse_ctx_errormsg (fru_parse_ctx));
  208. + fatal_with_errno(EXIT_FAILURE, "ipmi_fru_next: %s",
  209. + ipmi_fru_ctx_errormsg (fru_ctx));
  210. }
  211. else {
  212. /* Get all related sensors information */
  213. @@ -232,25 +262,25 @@ void nut_ipmi_close(void)
  214. }
  215. static const char* libfreeipmi_getfield (uint8_t language_code,
  216. - ipmi_fru_parse_field_t *field)
  217. + ipmi_fru_field_t *field)
  218. {
  219. - static char strbuf[IPMI_FRU_PARSE_AREA_STRING_MAX + 1];
  220. - unsigned int strbuflen = IPMI_FRU_PARSE_AREA_STRING_MAX;
  221. + static char strbuf[IPMI_FRU_AREA_STRING_MAX + 1];
  222. + unsigned int strbuflen = IPMI_FRU_AREA_STRING_MAX;
  223. if (!field->type_length_field_length)
  224. return NULL;
  225. - memset (strbuf, '\0', IPMI_FRU_PARSE_AREA_STRING_MAX + 1);
  226. + memset (strbuf, '\0', IPMI_FRU_AREA_STRING_MAX + 1);
  227. - if (ipmi_fru_parse_type_length_field_to_string (fru_parse_ctx,
  228. + if (ipmi_fru_type_length_field_to_string (fru_ctx,
  229. field->type_length_field,
  230. field->type_length_field_length,
  231. language_code,
  232. strbuf,
  233. &strbuflen) < 0)
  234. {
  235. - upsdebugx (2, "ipmi_fru_parse_type_length_field_to_string: %s",
  236. - ipmi_fru_parse_ctx_errormsg (fru_parse_ctx));
  237. + upsdebugx (2, "ipmi_fru_type_length_field_to_string: %s",
  238. + ipmi_fru_ctx_errormsg (fru_ctx));
  239. return NULL;
  240. }
  241. @@ -279,24 +309,20 @@ static float libfreeipmi_get_voltage (uint8_t voltage_code)
  242. static void libfreeipmi_cleanup()
  243. {
  244. /* cleanup */
  245. - if (fru_parse_ctx) {
  246. - ipmi_fru_parse_close_device_id (fru_parse_ctx);
  247. - ipmi_fru_parse_ctx_destroy (fru_parse_ctx);
  248. + if (fru_ctx) {
  249. + ipmi_fru_close_device_id (fru_ctx);
  250. + ipmi_fru_ctx_destroy (fru_ctx);
  251. }
  252. -#ifdef HAVE_FREEIPMI_11X_12X
  253. if (sdr_ctx) {
  254. ipmi_sdr_ctx_destroy (sdr_ctx);
  255. }
  256. -#else /* HAVE_FREEIPMI_11X_12X */
  257. - if (sdr_cache_ctx) {
  258. - ipmi_sdr_cache_ctx_destroy (sdr_cache_ctx);
  259. - }
  260. +#ifndef HAVE_FREEIPMI_11X_12X
  261. if (sdr_parse_ctx) {
  262. ipmi_sdr_parse_ctx_destroy (sdr_parse_ctx);
  263. }
  264. -#endif /* HAVE_FREEIPMI_11X_12X */
  265. +#endif
  266. if (ipmi_ctx) {
  267. ipmi_ctx_close (ipmi_ctx);
  268. @@ -342,7 +368,7 @@ static int libfreeipmi_get_psu_info (const void *areabuf,
  269. upsdebugx(1, "entering libfreeipmi_get_psu_info()");
  270. - if (ipmi_fru_parse_multirecord_power_supply_information (fru_parse_ctx,
  271. + if (ipmi_fru_multirecord_power_supply_information (fru_ctx,
  272. areabuf,
  273. area_length,
  274. &overall_capacity,
  275. @@ -368,8 +394,8 @@ static int libfreeipmi_get_psu_info (const void *areabuf,
  276. &total_combined_wattage,
  277. &predictive_fail_tachometer_lower_threshold) < 0)
  278. {
  279. - fatalx(EXIT_FAILURE, "ipmi_fru_parse_multirecord_power_supply_information: %s",
  280. - ipmi_fru_parse_ctx_errormsg (fru_parse_ctx));
  281. + fatalx(EXIT_FAILURE, "ipmi_fru_multirecord_power_supply_information: %s",
  282. + ipmi_fru_ctx_errormsg (fru_ctx));
  283. }
  284. ipmi_dev->overall_capacity = overall_capacity;
  285. @@ -383,6 +409,8 @@ static int libfreeipmi_get_psu_info (const void *areabuf,
  286. ipmi_dev->voltage = libfreeipmi_get_voltage(voltage_1);
  287. + upsdebugx(1, "libfreeipmi_get_psu_info() retrieved successfully");
  288. +
  289. return (0);
  290. }
  291. @@ -392,12 +420,12 @@ static int libfreeipmi_get_board_info (const void *areabuf,
  292. {
  293. uint8_t language_code;
  294. uint32_t mfg_date_time;
  295. - ipmi_fru_parse_field_t board_manufacturer;
  296. - ipmi_fru_parse_field_t board_product_name;
  297. - ipmi_fru_parse_field_t board_serial_number;
  298. - ipmi_fru_parse_field_t board_part_number;
  299. - ipmi_fru_parse_field_t board_fru_file_id;
  300. - ipmi_fru_parse_field_t board_custom_fields[IPMI_FRU_CUSTOM_FIELDS];
  301. + ipmi_fru_field_t board_manufacturer;
  302. + ipmi_fru_field_t board_product_name;
  303. + ipmi_fru_field_t board_serial_number;
  304. + ipmi_fru_field_t board_part_number;
  305. + ipmi_fru_field_t board_fru_file_id;
  306. + ipmi_fru_field_t board_custom_fields[IPMI_FRU_CUSTOM_FIELDS];
  307. const char *string = NULL;
  308. time_t timetmp;
  309. struct tm mfg_date_time_tm;
  310. @@ -406,15 +434,15 @@ static int libfreeipmi_get_board_info (const void *areabuf,
  311. upsdebugx(1, "entering libfreeipmi_get_board_info()");
  312. /* clear fields */
  313. - memset (&board_manufacturer, '\0', sizeof (ipmi_fru_parse_field_t));
  314. - memset (&board_product_name, '\0', sizeof (ipmi_fru_parse_field_t));
  315. - memset (&board_serial_number, '\0', sizeof (ipmi_fru_parse_field_t));
  316. - memset (&board_fru_file_id, '\0', sizeof (ipmi_fru_parse_field_t));
  317. + memset (&board_manufacturer, '\0', sizeof (ipmi_fru_field_t));
  318. + memset (&board_product_name, '\0', sizeof (ipmi_fru_field_t));
  319. + memset (&board_serial_number, '\0', sizeof (ipmi_fru_field_t));
  320. + memset (&board_fru_file_id, '\0', sizeof (ipmi_fru_field_t));
  321. memset (&board_custom_fields[0], '\0',
  322. - sizeof (ipmi_fru_parse_field_t) * IPMI_FRU_CUSTOM_FIELDS);
  323. + sizeof (ipmi_fru_field_t) * IPMI_FRU_CUSTOM_FIELDS);
  324. /* parse FRU buffer */
  325. - if (ipmi_fru_parse_board_info_area (fru_parse_ctx,
  326. + if (ipmi_fru_board_info_area (fru_ctx,
  327. areabuf,
  328. area_length,
  329. &language_code,
  330. @@ -428,8 +456,8 @@ static int libfreeipmi_get_board_info (const void *areabuf,
  331. IPMI_FRU_CUSTOM_FIELDS) < 0)
  332. {
  333. libfreeipmi_cleanup();
  334. - fatalx(EXIT_FAILURE, "ipmi_fru_parse_board_info_area: %s",
  335. - ipmi_fru_parse_ctx_errormsg (fru_parse_ctx));
  336. + fatalx(EXIT_FAILURE, "ipmi_fru_board_info_area: %s",
  337. + ipmi_fru_ctx_errormsg (fru_ctx));
  338. }
  339. @@ -498,113 +526,64 @@ static int libfreeipmi_get_sensors_info (IPMIDevice_t *ipmi_dev)
  340. ipmi_dev->sensors_count = 0;
  341. memset(ipmi_dev->sensors_id_list, 0, sizeof(ipmi_dev->sensors_id_list));
  342. -#ifdef HAVE_FREEIPMI_11X_12X
  343. if (!(sdr_ctx = ipmi_sdr_ctx_create ()))
  344. {
  345. libfreeipmi_cleanup();
  346. fatal_with_errno(EXIT_FAILURE, "ipmi_sdr_ctx_create()");
  347. }
  348. - if (ipmi_sdr_cache_open (sdr_ctx, ipmi_ctx, CACHE_LOCATION) < 0)
  349. - {
  350. - if (ipmi_sdr_ctx_errnum (sdr_ctx) != IPMI_SDR_ERR_CACHE_READ_CACHE_DOES_NOT_EXIST)
  351. - {
  352. - libfreeipmi_cleanup();
  353. - fatal_with_errno(EXIT_FAILURE, "ipmi_sdr_cache_open: %s",
  354. - ipmi_sdr_ctx_errormsg (sdr_ctx));
  355. - }
  356. - }
  357. -#else /* HAVE_FREEIPMI_11X_12X */
  358. - if (!(sdr_cache_ctx = ipmi_sdr_cache_ctx_create ()))
  359. - {
  360. - libfreeipmi_cleanup();
  361. - fatal_with_errno(EXIT_FAILURE, "ipmi_sdr_cache_ctx_create()");
  362. - }
  363. -
  364. +#ifndef HAVE_FREEIPMI_11X_12X
  365. if (!(sdr_parse_ctx = ipmi_sdr_parse_ctx_create ()))
  366. {
  367. libfreeipmi_cleanup();
  368. fatal_with_errno(EXIT_FAILURE, "ipmi_sdr_parse_ctx_create()");
  369. }
  370. +#endif
  371. - if (ipmi_sdr_cache_open (sdr_cache_ctx, ipmi_ctx, CACHE_LOCATION) < 0)
  372. + if (ipmi_sdr_cache_open (sdr_ctx, ipmi_ctx, CACHE_LOCATION) < 0)
  373. {
  374. - if (ipmi_sdr_cache_ctx_errnum (sdr_cache_ctx) != IPMI_SDR_CACHE_ERR_CACHE_READ_CACHE_DOES_NOT_EXIST)
  375. + if (ipmi_sdr_ctx_errnum (sdr_ctx) != IPMI_SDR_ERR_CACHE_READ_CACHE_DOES_NOT_EXIST)
  376. {
  377. libfreeipmi_cleanup();
  378. fatal_with_errno(EXIT_FAILURE, "ipmi_sdr_cache_open: %s",
  379. - ipmi_sdr_cache_ctx_errormsg (sdr_cache_ctx));
  380. + ipmi_sdr_ctx_errormsg (sdr_ctx));
  381. }
  382. }
  383. -#endif /* HAVE_FREEIPMI_11X_12X */
  384. -#ifdef HAVE_FREEIPMI_11X_12X
  385. if (ipmi_sdr_ctx_errnum (sdr_ctx) == IPMI_SDR_ERR_CACHE_READ_CACHE_DOES_NOT_EXIST)
  386. {
  387. if (ipmi_sdr_cache_create (sdr_ctx,
  388. ipmi_ctx, CACHE_LOCATION,
  389. IPMI_SDR_CACHE_CREATE_FLAGS_DEFAULT,
  390. +#ifndef HAVE_FREEIPMI_11X_12X
  391. + IPMI_SDR_CACHE_VALIDATION_FLAGS_DEFAULT,
  392. +#endif
  393. NULL, NULL) < 0)
  394. {
  395. libfreeipmi_cleanup();
  396. fatal_with_errno(EXIT_FAILURE, "ipmi_sdr_cache_create: %s",
  397. ipmi_sdr_ctx_errormsg (sdr_ctx));
  398. }
  399. - if (ipmi_sdr_cache_open (sdr_ctx,
  400. - ipmi_ctx, CACHE_LOCATION) < 0)
  401. + if (ipmi_sdr_cache_open (sdr_ctx, ipmi_ctx, CACHE_LOCATION) < 0)
  402. {
  403. if (ipmi_sdr_ctx_errnum (sdr_ctx) != IPMI_SDR_ERR_CACHE_READ_CACHE_DOES_NOT_EXIST)
  404. {
  405. - libfreeipmi_cleanup();
  406. - fatal_with_errno(EXIT_FAILURE, "ipmi_sdr_cache_open: %s",
  407. - ipmi_sdr_ctx_errormsg (sdr_ctx));
  408. - }
  409. - }
  410. - }
  411. -#else /* HAVE_FREEIPMI_11X_12X */
  412. - if (ipmi_sdr_cache_ctx_errnum (sdr_cache_ctx) == IPMI_SDR_CACHE_ERR_CACHE_READ_CACHE_DOES_NOT_EXIST)
  413. - {
  414. - if (ipmi_sdr_cache_create (sdr_cache_ctx,
  415. - ipmi_ctx, CACHE_LOCATION,
  416. - IPMI_SDR_CACHE_CREATE_FLAGS_DEFAULT,
  417. - IPMI_SDR_CACHE_VALIDATION_FLAGS_DEFAULT,
  418. - NULL, NULL) < 0)
  419. - {
  420. - libfreeipmi_cleanup();
  421. - fatal_with_errno(EXIT_FAILURE, "ipmi_sdr_cache_create: %s",
  422. - ipmi_sdr_cache_ctx_errormsg (sdr_cache_ctx));
  423. - }
  424. - if (ipmi_sdr_cache_open (sdr_cache_ctx,
  425. - ipmi_ctx, CACHE_LOCATION) < 0)
  426. - {
  427. - if (ipmi_sdr_cache_ctx_errnum (sdr_cache_ctx) != IPMI_SDR_CACHE_ERR_CACHE_READ_CACHE_DOES_NOT_EXIST)
  428. - {
  429. - libfreeipmi_cleanup();
  430. - fatal_with_errno(EXIT_FAILURE, "ipmi_sdr_cache_open: %s",
  431. - ipmi_sdr_cache_ctx_errormsg (sdr_cache_ctx));
  432. + libfreeipmi_cleanup();
  433. + fatal_with_errno(EXIT_FAILURE, "ipmi_sdr_cache_open: %s",
  434. + ipmi_sdr_ctx_errormsg (sdr_ctx));
  435. }
  436. }
  437. }
  438. -#endif /* HAVE_FREEIPMI_11X_12X */
  439. -#ifdef HAVE_FREEIPMI_11X_12X
  440. - if (ipmi_sdr_cache_record_count (sdr_ctx, &record_count) < 0) {
  441. + if (ipmi_sdr_cache_record_count (sdr_ctx, &record_count) < 0) {
  442. fprintf (stderr,
  443. - "ipmi_sdr_cache_record_count: %s",
  444. + "ipmi_sdr_cache_record_count: %s\n",
  445. ipmi_sdr_ctx_errormsg (sdr_ctx));
  446. goto cleanup;
  447. }
  448. -#else
  449. - if (ipmi_sdr_cache_record_count (sdr_cache_ctx, &record_count) < 0)
  450. - {
  451. - fprintf (stderr,
  452. - "ipmi_sdr_cache_record_count: %s",
  453. - ipmi_sdr_cache_ctx_errormsg (sdr_cache_ctx));
  454. - goto cleanup;
  455. - }
  456. -#endif /* HAVE_FREEIPMI_11X_12X */
  457. -#ifdef HAVE_FREEIPMI_11X_12X
  458. + upsdebugx(3, "Found %i records in SDR cache", record_count);
  459. +
  460. for (i = 0; i < record_count; i++, ipmi_sdr_cache_next (sdr_ctx))
  461. {
  462. memset (sdr_record, '\0', IPMI_SDR_MAX_RECORD_LENGTH);
  463. @@ -613,50 +592,29 @@ static int libfreeipmi_get_sensors_info (IPMIDevice_t *ipmi_dev)
  464. sdr_record,
  465. IPMI_SDR_MAX_RECORD_LENGTH)) < 0)
  466. {
  467. - fprintf (stderr, "ipmi_sdr_cache_record_read: %s",
  468. + fprintf (stderr, "ipmi_sdr_cache_record_read: %s\n",
  469. ipmi_sdr_ctx_errormsg (sdr_ctx));
  470. goto cleanup;
  471. }
  472. - if (ipmi_sdr_parse_record_id_and_type (sdr_ctx,
  473. + if (ipmi_sdr_parse_record_id_and_type (SDR_PARSE_CTX,
  474. sdr_record,
  475. sdr_record_len,
  476. NULL,
  477. &record_type) < 0)
  478. {
  479. - fprintf (stderr, "ipmi_sdr_parse_record_id_and_type: %s",
  480. + fprintf (stderr, "ipmi_sdr_parse_record_id_and_type: %s\n",
  481. ipmi_sdr_ctx_errormsg (sdr_ctx));
  482. goto cleanup;
  483. }
  484. -#else
  485. - for (i = 0; i < record_count; i++, ipmi_sdr_cache_next (sdr_cache_ctx))
  486. - {
  487. - memset (sdr_record, '\0', IPMI_SDR_MAX_RECORD_LENGTH);
  488. - if ((sdr_record_len = ipmi_sdr_cache_record_read (sdr_cache_ctx,
  489. - sdr_record,
  490. - IPMI_SDR_MAX_RECORD_LENGTH)) < 0)
  491. - {
  492. - fprintf (stderr, "ipmi_sdr_cache_record_read: %s",
  493. - ipmi_sdr_cache_ctx_errormsg (sdr_cache_ctx));
  494. - goto cleanup;
  495. - }
  496. - if (ipmi_sdr_parse_record_id_and_type (sdr_parse_ctx,
  497. - sdr_record,
  498. - sdr_record_len,
  499. - NULL,
  500. - &record_type) < 0)
  501. - {
  502. - fprintf (stderr, "ipmi_sdr_parse_record_id_and_type: %s",
  503. - ipmi_sdr_parse_ctx_errormsg (sdr_parse_ctx));
  504. - goto cleanup;
  505. - }
  506. -#endif /* HAVE_FREEIPMI_11X_12X */
  507. + upsdebugx (5, "Checking record %i (/%i)", i, record_count);
  508. - if (record_type != IPMI_SDR_FORMAT_FRU_DEVICE_LOCATOR_RECORD)
  509. + if (record_type != IPMI_SDR_FORMAT_FRU_DEVICE_LOCATOR_RECORD) {
  510. + upsdebugx(1, "=======> not device locator (%i)!!", record_type);
  511. continue;
  512. + }
  513. -#ifdef HAVE_FREEIPMI_11X_12X
  514. - if (ipmi_sdr_parse_fru_device_locator_parameters (sdr_ctx,
  515. + if (ipmi_sdr_parse_fru_device_locator_parameters (SDR_PARSE_CTX,
  516. sdr_record,
  517. sdr_record_len,
  518. NULL,
  519. @@ -666,86 +624,49 @@ static int libfreeipmi_get_sensors_info (IPMIDevice_t *ipmi_dev)
  520. &logical_physical_fru_device,
  521. NULL) < 0)
  522. {
  523. - fprintf (stderr, "ipmi_sdr_parse_fru_device_locator_parameters: %s",
  524. + fprintf (stderr, "ipmi_sdr_parse_fru_device_locator_parameters: %s\n",
  525. ipmi_sdr_ctx_errormsg (sdr_ctx));
  526. goto cleanup;
  527. }
  528. -#else /* HAVE_FREEIPMI_11X_12X */
  529. - if (ipmi_sdr_parse_fru_device_locator_parameters (sdr_parse_ctx,
  530. - sdr_record,
  531. - sdr_record_len,
  532. - NULL,
  533. - &logical_fru_device_device_slave_address,
  534. - NULL,
  535. - NULL,
  536. - &logical_physical_fru_device,
  537. - NULL) < 0)
  538. - {
  539. - fprintf (stderr, "ipmi_sdr_parse_fru_device_locator_parameters: %s",
  540. - ipmi_sdr_parse_ctx_errormsg (sdr_parse_ctx));
  541. - goto cleanup;
  542. - }
  543. -#endif /* HAVE_FREEIPMI_11X_12X */
  544. +
  545. + upsdebugx(2, "Checking device %i/%i", logical_physical_fru_device,
  546. + logical_fru_device_device_slave_address);
  547. if (logical_physical_fru_device
  548. && logical_fru_device_device_slave_address == ipmi_dev->ipmi_id)
  549. {
  550. found_device_id++;
  551. -#ifdef HAVE_FREEIPMI_11X_12X
  552. - if (ipmi_sdr_parse_fru_entity_id_and_instance (sdr_ctx,
  553. + if (ipmi_sdr_parse_fru_entity_id_and_instance (SDR_PARSE_CTX,
  554. sdr_record,
  555. sdr_record_len,
  556. &entity_id,
  557. &entity_instance) < 0)
  558. {
  559. fprintf (stderr,
  560. - "ipmi_sdr_parse_fru_entity_id_and_instance: %s",
  561. + "ipmi_sdr_parse_fru_entity_id_and_instance: %s\n",
  562. ipmi_sdr_ctx_errormsg (sdr_ctx));
  563. goto cleanup;
  564. }
  565. -#else /* HAVE_FREEIPMI_11X_12X */
  566. - if (ipmi_sdr_parse_fru_entity_id_and_instance (sdr_parse_ctx,
  567. - sdr_record,
  568. - sdr_record_len,
  569. - &entity_id,
  570. - &entity_instance) < 0)
  571. - {
  572. - fprintf (stderr,
  573. - "ipmi_sdr_parse_fru_entity_id_and_instance: %s",
  574. - ipmi_sdr_parse_ctx_errormsg (sdr_parse_ctx));
  575. - goto cleanup;
  576. - }
  577. -#endif /* HAVE_FREEIPMI_11X_12X */
  578. break;
  579. }
  580. }
  581. if (!found_device_id)
  582. {
  583. - fprintf (stderr, "Couldn't find device id %d", ipmi_dev->ipmi_id);
  584. + fprintf (stderr, "Couldn't find device id %d\n", ipmi_dev->ipmi_id);
  585. goto cleanup;
  586. }
  587. else
  588. upsdebugx(1, "Found device id %d", ipmi_dev->ipmi_id);
  589. -#ifdef HAVE_FREEIPMI_11X_12X
  590. if (ipmi_sdr_cache_first (sdr_ctx) < 0)
  591. {
  592. - fprintf (stderr, "ipmi_sdr_cache_first: %s",
  593. + fprintf (stderr, "ipmi_sdr_cache_first: %s\n",
  594. ipmi_sdr_ctx_errormsg (sdr_ctx));
  595. goto cleanup;
  596. }
  597. -#else /* HAVE_FREEIPMI_11X_12X */
  598. - if (ipmi_sdr_cache_first (sdr_cache_ctx) < 0)
  599. - {
  600. - fprintf (stderr, "ipmi_sdr_cache_first: %s",
  601. - ipmi_sdr_cache_ctx_errormsg (sdr_cache_ctx));
  602. - goto cleanup;
  603. - }
  604. -#endif /* HAVE_FREEIPMI_11X_12X */
  605. -#ifdef HAVE_FREEIPMI_11X_12X
  606. for (i = 0; i < record_count; i++, ipmi_sdr_cache_next (sdr_ctx))
  607. {
  608. /* uint8_t sdr_record[IPMI_SDR_CACHE_MAX_SDR_RECORD_LENGTH];
  609. @@ -757,49 +678,21 @@ static int libfreeipmi_get_sensors_info (IPMIDevice_t *ipmi_dev)
  610. sdr_record,
  611. IPMI_SDR_MAX_RECORD_LENGTH)) < 0)
  612. {
  613. - fprintf (stderr, "ipmi_sdr_cache_record_read: %s",
  614. + fprintf (stderr, "ipmi_sdr_cache_record_read: %s\n",
  615. ipmi_sdr_ctx_errormsg (sdr_ctx));
  616. goto cleanup;
  617. }
  618. - if (ipmi_sdr_parse_record_id_and_type (sdr_ctx,
  619. + if (ipmi_sdr_parse_record_id_and_type (SDR_PARSE_CTX,
  620. sdr_record,
  621. sdr_record_len,
  622. &record_id,
  623. &record_type) < 0)
  624. {
  625. - fprintf (stderr, "ipmi_sdr_parse_record_id_and_type: %s",
  626. + fprintf (stderr, "ipmi_sdr_parse_record_id_and_type: %s\n",
  627. ipmi_sdr_ctx_errormsg (sdr_ctx));
  628. goto cleanup;
  629. }
  630. -#else /* HAVE_FREEIPMI_11X_12X */
  631. - for (i = 0; i < record_count; i++, ipmi_sdr_cache_next (sdr_cache_ctx))
  632. - {
  633. - /* uint8_t sdr_record[IPMI_SDR_CACHE_MAX_SDR_RECORD_LENGTH];
  634. - uint8_t record_type, tmp_entity_id, tmp_entity_instance;
  635. - int sdr_record_len; */
  636. -
  637. - memset (sdr_record, '\0', IPMI_SDR_MAX_RECORD_LENGTH);
  638. - if ((sdr_record_len = ipmi_sdr_cache_record_read (sdr_cache_ctx,
  639. - sdr_record,
  640. - IPMI_SDR_MAX_RECORD_LENGTH)) < 0)
  641. - {
  642. - fprintf (stderr, "ipmi_sdr_cache_record_read: %s",
  643. - ipmi_sdr_cache_ctx_errormsg (sdr_cache_ctx));
  644. - goto cleanup;
  645. - }
  646. -
  647. - if (ipmi_sdr_parse_record_id_and_type (sdr_parse_ctx,
  648. - sdr_record,
  649. - sdr_record_len,
  650. - &record_id,
  651. - &record_type) < 0)
  652. - {
  653. - fprintf (stderr, "ipmi_sdr_parse_record_id_and_type: %s",
  654. - ipmi_sdr_parse_ctx_errormsg (sdr_parse_ctx));
  655. - goto cleanup;
  656. - }
  657. -#endif /* HAVE_FREEIPMI_11X_12X */
  658. upsdebugx (5, "Checking record %i (/%i)", record_id, record_count);
  659. @@ -809,31 +702,17 @@ static int libfreeipmi_get_sensors_info (IPMIDevice_t *ipmi_dev)
  660. continue;
  661. }
  662. -#ifdef HAVE_FREEIPMI_11X_12X
  663. - if (ipmi_sdr_parse_entity_id_instance_type (sdr_ctx,
  664. + if (ipmi_sdr_parse_entity_id_instance_type (SDR_PARSE_CTX,
  665. sdr_record,
  666. sdr_record_len,
  667. &tmp_entity_id,
  668. &tmp_entity_instance,
  669. NULL) < 0)
  670. {
  671. - fprintf (stderr, "ipmi_sdr_parse_entity_instance_type: %s",
  672. + fprintf (stderr, "ipmi_sdr_parse_entity_instance_type: %s\n",
  673. ipmi_sdr_ctx_errormsg (sdr_ctx));
  674. goto cleanup;
  675. }
  676. -#else /* HAVE_FREEIPMI_11X_12X */
  677. - if (ipmi_sdr_parse_entity_id_instance_type (sdr_parse_ctx,
  678. - sdr_record,
  679. - sdr_record_len,
  680. - &tmp_entity_id,
  681. - &tmp_entity_instance,
  682. - NULL) < 0)
  683. - {
  684. - fprintf (stderr, "ipmi_sdr_parse_entity_instance_type: %s",
  685. - ipmi_sdr_parse_ctx_errormsg (sdr_parse_ctx));
  686. - goto cleanup;
  687. - }
  688. -#endif /* HAVE_FREEIPMI_11X_12X */
  689. if (tmp_entity_id == entity_id
  690. && tmp_entity_instance == entity_instance)
  691. @@ -850,15 +729,11 @@ static int libfreeipmi_get_sensors_info (IPMIDevice_t *ipmi_dev)
  692. cleanup:
  693. /* Cleanup */
  694. -#ifdef HAVE_FREEIPMI_11X_12X
  695. if (sdr_ctx) {
  696. ipmi_sdr_ctx_destroy (sdr_ctx);
  697. }
  698. -#else /* HAVE_FREEIPMI_11X_12X */
  699. - if (sdr_cache_ctx) {
  700. - ipmi_sdr_cache_ctx_destroy (sdr_cache_ctx);
  701. - }
  702. +#ifndef HAVE_FREEIPMI_11X_12X
  703. if (sdr_parse_ctx) {
  704. ipmi_sdr_parse_ctx_destroy (sdr_parse_ctx);
  705. }
  706. diff --git a/m4/nut_check_libfreeipmi.m4 b/m4/nut_check_libfreeipmi.m4
  707. index 72e7819..5b2eae9 100644
  708. --- a/m4/nut_check_libfreeipmi.m4
  709. +++ b/m4/nut_check_libfreeipmi.m4
  710. @@ -66,7 +66,6 @@ if test -z "${nut_have_libfreeipmi_seen}"; then
  711. dnl when version cannot be tested (prior to 1.0.5, with no pkg-config)
  712. dnl we have to check for some specific functions
  713. AC_SEARCH_LIBS([ipmi_ctx_find_inband], [freeipmi], [], [nut_have_freeipmi=no])
  714. - AC_SEARCH_LIBS([ipmi_fru_parse_ctx_create], [freeipmi], [], [nut_have_freeipmi=no])
  715. AC_SEARCH_LIBS([ipmi_monitoring_init], [ipmimonitoring], [nut_have_freeipmi_monitoring=yes], [nut_have_freeipmi_monitoring=no])
  716. AC_SEARCH_LIBS([ipmi_monitoring_sensor_read_record_id], [ipmimonitoring], [], [nut_have_freeipmi_monitoring=no])
  717. diff --git a/tools/nut-scanner/scan_ipmi.c b/tools/nut-scanner/scan_ipmi.c
  718. index d650efa..c1ec78a 100644
  719. --- a/tools/nut-scanner/scan_ipmi.c
  720. +++ b/tools/nut-scanner/scan_ipmi.c
  721. @@ -34,24 +34,51 @@ static char * libname = "libfreeipmi";
  722. static lt_dlhandle dl_handle = NULL;
  723. static const char *dl_error = NULL;
  724. -static int (*nut_ipmi_fru_parse_close_device_id) (ipmi_fru_parse_ctx_t ctx);
  725. -static void (*nut_ipmi_fru_parse_ctx_destroy) (ipmi_fru_parse_ctx_t ctx);
  726. #ifdef HAVE_FREEIPMI_11X_12X
  727. -static void (*nut_ipmi_sdr_ctx_destroy) (ipmi_sdr_ctx_t ctx);
  728. + /* Functions symbols remapping */
  729. + #define IPMI_FRU_CLOSE_DEVICE_ID "ipmi_fru_close_device_id"
  730. + #define IPMI_FRU_CTX_DESTROY "ipmi_fru_ctx_destroy"
  731. + #define IPMI_FRU_CTX_CREATE "ipmi_fru_ctx_create"
  732. + #define IPMI_FRU_CTX_SET_FLAGS "ipmi_fru_ctx_set_flags"
  733. + #define IPMI_FRU_OPEN_DEVICE_ID "ipmi_fru_open_device_id"
  734. + #define IPMI_FRU_CTX_ERRORMSG "ipmi_fru_ctx_errormsg"
  735. + #define IPMI_FRU_READ_DATA_AREA "ipmi_fru_read_data_area"
  736. + #define IPMI_FRU_PARSE_NEXT "ipmi_fru_next"
  737. + typedef ipmi_fru_ctx_t ipmi_fru_parse_ctx_t;
  738. + typedef ipmi_sdr_ctx_t ipmi_sdr_cache_ctx_t;
  739. + /* Functions remapping */
  740. + static void (*nut_ipmi_sdr_ctx_destroy) (ipmi_sdr_ctx_t ctx);
  741. #else /* HAVE_FREEIPMI_11X_12X */
  742. -static void (*nut_ipmi_sdr_cache_ctx_destroy) (ipmi_sdr_cache_ctx_t ctx);
  743. -static void (*nut_ipmi_sdr_parse_ctx_destroy) (ipmi_sdr_parse_ctx_t ctx);
  744. + #define IPMI_FRU_AREA_SIZE_MAX IPMI_FRU_PARSE_AREA_SIZE_MAX
  745. + #define IPMI_FRU_FLAGS_SKIP_CHECKSUM_CHECKS IPMI_FRU_PARSE_FLAGS_SKIP_CHECKSUM_CHECKS
  746. + #define IPMI_FRU_AREA_TYPE_MULTIRECORD_POWER_SUPPLY_INFORMATION IPMI_FRU_PARSE_AREA_TYPE_MULTIRECORD_POWER_SUPPLY_INFORMATION
  747. + /* Functions symbols remapping */
  748. + #define IPMI_FRU_CLOSE_DEVICE_ID "ipmi_fru_parse_close_device_id"
  749. + #define IPMI_FRU_CTX_DESTROY "ipmi_fru_parse_ctx_destroy"
  750. + #define IPMI_FRU_CTX_CREATE "ipmi_fru_parse_ctx_create"
  751. + #define IPMI_FRU_CTX_SET_FLAGS "ipmi_fru_parse_ctx_set_flags"
  752. + #define IPMI_FRU_OPEN_DEVICE_ID "ipmi_fru_parse_open_device_id"
  753. + #define IPMI_FRU_CTX_ERRORMSG "ipmi_fru_parse_ctx_errormsg"
  754. + #define IPMI_FRU_READ_DATA_AREA "ipmi_fru_parse_read_data_area"
  755. + #define IPMI_FRU_PARSE_NEXT "ipmi_fru_parse_next"
  756. + /* Functions remapping */
  757. + static void (*nut_ipmi_sdr_cache_ctx_destroy) (ipmi_sdr_cache_ctx_t ctx);
  758. + static void (*nut_ipmi_sdr_parse_ctx_destroy) (ipmi_sdr_parse_ctx_t ctx);
  759. #endif /* HAVE_FREEIPMI_11X_12X */
  760. -static ipmi_fru_parse_ctx_t (*nut_ipmi_fru_parse_ctx_create) (ipmi_ctx_t ipmi_ctx);
  761. -static int (*nut_ipmi_fru_parse_ctx_set_flags) (ipmi_fru_parse_ctx_t ctx, unsigned int flags);
  762. -static int (*nut_ipmi_fru_parse_open_device_id) (ipmi_fru_parse_ctx_t ctx, uint8_t fru_device_id);
  763. -static char * (*nut_ipmi_fru_parse_ctx_errormsg) (ipmi_fru_parse_ctx_t ctx);
  764. -static int (*nut_ipmi_fru_parse_read_data_area) (ipmi_fru_parse_ctx_t ctx,
  765. +
  766. +
  767. +static int (*nut_ipmi_fru_close_device_id) (ipmi_fru_parse_ctx_t ctx);
  768. +static void (*nut_ipmi_fru_ctx_destroy) (ipmi_fru_parse_ctx_t ctx);
  769. +static ipmi_fru_parse_ctx_t (*nut_ipmi_fru_ctx_create) (ipmi_ctx_t ipmi_ctx);
  770. +static int (*nut_ipmi_fru_ctx_set_flags) (ipmi_fru_parse_ctx_t ctx, unsigned int flags);
  771. +static int (*nut_ipmi_fru_open_device_id) (ipmi_fru_parse_ctx_t ctx, uint8_t fru_device_id);
  772. +static char * (*nut_ipmi_fru_ctx_errormsg) (ipmi_fru_parse_ctx_t ctx);
  773. +static int (*nut_ipmi_fru_read_data_area) (ipmi_fru_parse_ctx_t ctx,
  774. unsigned int *area_type,
  775. unsigned int *area_length,
  776. void *areabuf,
  777. unsigned int areabuflen);
  778. -static int (*nut_ipmi_fru_parse_next) (ipmi_fru_parse_ctx_t ctx);
  779. +static int (*nut_ipmi_fru_next) (ipmi_fru_parse_ctx_t ctx);
  780. static ipmi_ctx_t (*nut_ipmi_ctx_create) (void);
  781. static int (*nut_ipmi_ctx_find_inband) (ipmi_ctx_t ctx,
  782. ipmi_driver_type_t *driver_type,
  783. @@ -92,12 +119,12 @@ int nutscan_load_ipmi_library()
  784. /* Clear any existing error */
  785. lt_dlerror();
  786. - *(void **) (&nut_ipmi_fru_parse_close_device_id) = lt_dlsym(dl_handle, "ipmi_fru_parse_close_device_id");
  787. + *(void **) (&nut_ipmi_fru_close_device_id) = lt_dlsym(dl_handle, IPMI_FRU_CLOSE_DEVICE_ID);
  788. if ((dl_error = lt_dlerror()) != NULL) {
  789. goto err;
  790. }
  791. - *(void **) (&nut_ipmi_fru_parse_ctx_destroy) = lt_dlsym(dl_handle, "ipmi_fru_parse_ctx_destroy");
  792. + *(void **) (&nut_ipmi_fru_ctx_destroy) = lt_dlsym(dl_handle, IPMI_FRU_CTX_DESTROY);
  793. if ((dl_error = lt_dlerror()) != NULL) {
  794. goto err;
  795. }
  796. @@ -122,32 +149,32 @@ int nutscan_load_ipmi_library()
  797. }
  798. #endif /* HAVE_FREEIPMI_11X_12X */
  799. - *(void **) (&nut_ipmi_fru_parse_ctx_create) = lt_dlsym(dl_handle, "ipmi_fru_parse_ctx_create");
  800. + *(void **) (&nut_ipmi_fru_ctx_create) = lt_dlsym(dl_handle, IPMI_FRU_CTX_CREATE);
  801. if ((dl_error = lt_dlerror()) != NULL) {
  802. goto err;
  803. }
  804. - *(void **) (&nut_ipmi_fru_parse_ctx_set_flags) = lt_dlsym(dl_handle, "ipmi_fru_parse_ctx_set_flags");
  805. + *(void **) (&nut_ipmi_fru_ctx_set_flags) = lt_dlsym(dl_handle, IPMI_FRU_CTX_SET_FLAGS);
  806. if ((dl_error = lt_dlerror()) != NULL) {
  807. goto err;
  808. }
  809. - *(void **) (&nut_ipmi_fru_parse_open_device_id) = lt_dlsym(dl_handle, "ipmi_fru_parse_open_device_id");
  810. + *(void **) (&nut_ipmi_fru_open_device_id) = lt_dlsym(dl_handle, IPMI_FRU_OPEN_DEVICE_ID);
  811. if ((dl_error = lt_dlerror()) != NULL) {
  812. goto err;
  813. }
  814. - *(void **) (&nut_ipmi_fru_parse_ctx_errormsg) = lt_dlsym(dl_handle, "ipmi_fru_parse_ctx_errormsg");
  815. + *(void **) (&nut_ipmi_fru_ctx_errormsg) = lt_dlsym(dl_handle, IPMI_FRU_CTX_ERRORMSG);
  816. if ((dl_error = lt_dlerror()) != NULL) {
  817. goto err;
  818. }
  819. - *(void **) (&nut_ipmi_fru_parse_read_data_area) = lt_dlsym(dl_handle, "ipmi_fru_parse_read_data_area");
  820. + *(void **) (&nut_ipmi_fru_read_data_area) = lt_dlsym(dl_handle, IPMI_FRU_READ_DATA_AREA);
  821. if ((dl_error = lt_dlerror()) != NULL) {
  822. goto err;
  823. }
  824. - *(void **) (&nut_ipmi_fru_parse_next) = lt_dlsym(dl_handle, "ipmi_fru_parse_next");
  825. + *(void **) (&nut_ipmi_fru_next) = lt_dlsym(dl_handle, IPMI_FRU_PARSE_NEXT);
  826. if ((dl_error = lt_dlerror()) != NULL) {
  827. goto err;
  828. }
  829. @@ -179,7 +206,7 @@ int nutscan_load_ipmi_library()
  830. return 1;
  831. err:
  832. - fprintf(stderr, "Cannot load IPMI library (%s) : %s. IPMI search disabled.\n", libname, dl_error);
  833. + fprintf(stderr, "Cannot load IPMI library (%s) : %s. IPMI search disabled.\n", libname, dl_error);
  834. dl_handle = (void *)1;
  835. lt_dlexit();
  836. return 0;
  837. @@ -197,8 +224,8 @@ static void nut_freeipmi_cleanup(ipmi_fru_parse_ctx_t fru_parse_ctx,
  838. #endif /* HAVE_FREEIPMI_11X_12X */
  839. {
  840. if (fru_parse_ctx) {
  841. - (*nut_ipmi_fru_parse_close_device_id) (fru_parse_ctx);
  842. - (*nut_ipmi_fru_parse_ctx_destroy) (fru_parse_ctx);
  843. + (*nut_ipmi_fru_close_device_id) (fru_parse_ctx);
  844. + (*nut_ipmi_fru_ctx_destroy) (fru_parse_ctx);
  845. }
  846. #ifdef HAVE_FREEIPMI_11X_12X
  847. @@ -226,7 +253,7 @@ int is_ipmi_device_supported(ipmi_ctx_t ipmi_ctx, int ipmi_id)
  848. int ret = -1;
  849. unsigned int area_type = 0;
  850. unsigned int area_length = 0;
  851. - uint8_t areabuf[IPMI_FRU_PARSE_AREA_SIZE_MAX+1];
  852. + uint8_t areabuf[IPMI_FRU_AREA_SIZE_MAX+1];
  853. ipmi_fru_parse_ctx_t fru_parse_ctx = NULL;
  854. #ifdef HAVE_FREEIPMI_11X_12X
  855. ipmi_sdr_ctx_t sdr_ctx = NULL;
  856. @@ -236,14 +263,14 @@ int is_ipmi_device_supported(ipmi_ctx_t ipmi_ctx, int ipmi_id)
  857. #endif /* HAVE_FREEIPMI_11X_12X */
  858. /* Parse FRU information */
  859. - if (!(fru_parse_ctx = (*nut_ipmi_fru_parse_ctx_create) (ipmi_ctx)))
  860. + if (!(fru_parse_ctx = (*nut_ipmi_fru_ctx_create) (ipmi_ctx)))
  861. {
  862. fprintf(stderr, "ipmi_fru_parse_ctx_create()\n");
  863. return 0;
  864. }
  865. -
  866. +fprintf(stdout, "There.1\n");
  867. /* lots of motherboards calculate checksums incorrectly */
  868. - if ((*nut_ipmi_fru_parse_ctx_set_flags) (fru_parse_ctx, IPMI_FRU_PARSE_FLAGS_SKIP_CHECKSUM_CHECKS) < 0)
  869. + if ((*nut_ipmi_fru_ctx_set_flags) (fru_parse_ctx, IPMI_FRU_FLAGS_SKIP_CHECKSUM_CHECKS) < 0)
  870. {
  871. #ifdef HAVE_FREEIPMI_11X_12X
  872. nut_freeipmi_cleanup(fru_parse_ctx, sdr_ctx);
  873. @@ -252,8 +279,8 @@ int is_ipmi_device_supported(ipmi_ctx_t ipmi_ctx, int ipmi_id)
  874. #endif /* HAVE_FREEIPMI_11X_12X */
  875. return 0;
  876. }
  877. -
  878. - if ((*nut_ipmi_fru_parse_open_device_id) (fru_parse_ctx, ipmi_id) < 0)
  879. +fprintf(stdout, "There.2\n");
  880. + if ((*nut_ipmi_fru_open_device_id) (fru_parse_ctx, ipmi_id) < 0)
  881. {
  882. #ifdef HAVE_FREEIPMI_11X_12X
  883. nut_freeipmi_cleanup(fru_parse_ctx, sdr_ctx);
  884. @@ -265,17 +292,18 @@ int is_ipmi_device_supported(ipmi_ctx_t ipmi_ctx, int ipmi_id)
  885. do
  886. {
  887. +fprintf(stdout, "There.3\n");
  888. /* clear fields */
  889. area_type = 0;
  890. area_length = 0;
  891. - memset (areabuf, '\0', IPMI_FRU_PARSE_AREA_SIZE_MAX + 1);
  892. + memset (areabuf, '\0', IPMI_FRU_AREA_SIZE_MAX + 1);
  893. /* parse FRU buffer */
  894. - if ((*nut_ipmi_fru_parse_read_data_area) (fru_parse_ctx,
  895. + if ((*nut_ipmi_fru_read_data_area) (fru_parse_ctx,
  896. &area_type,
  897. &area_length,
  898. areabuf,
  899. - IPMI_FRU_PARSE_AREA_SIZE_MAX) < 0)
  900. + IPMI_FRU_AREA_SIZE_MAX) < 0)
  901. {
  902. #ifdef HAVE_FREEIPMI_11X_12X
  903. nut_freeipmi_cleanup(fru_parse_ctx, sdr_ctx);
  904. @@ -287,7 +315,7 @@ int is_ipmi_device_supported(ipmi_ctx_t ipmi_ctx, int ipmi_id)
  905. if (area_length)
  906. {
  907. - if (area_type == IPMI_FRU_PARSE_AREA_TYPE_MULTIRECORD_POWER_SUPPLY_INFORMATION)
  908. + if (area_type == IPMI_FRU_AREA_TYPE_MULTIRECORD_POWER_SUPPLY_INFORMATION)
  909. {
  910. /* Found a POWER_SUPPLY record */
  911. #ifdef HAVE_FREEIPMI_11X_12X
  912. @@ -298,7 +326,7 @@ int is_ipmi_device_supported(ipmi_ctx_t ipmi_ctx, int ipmi_id)
  913. return 1;
  914. }
  915. }
  916. - } while ((ret = (*nut_ipmi_fru_parse_next) (fru_parse_ctx)) == 1);
  917. + } while ((ret = (*nut_ipmi_fru_next) (fru_parse_ctx)) == 1);
  918. /* No need for further errors checking */
  919. #ifdef HAVE_FREEIPMI_11X_12X
  920. @@ -322,7 +350,7 @@ nutscan_device_t * nutscan_scan_ipmi()
  921. if( !nutscan_avail_ipmi ) {
  922. return NULL;
  923. }
  924. -
  925. +fprintf(stdout, "There1\n");
  926. /* Initialize the FreeIPMI library. */
  927. if (!(ipmi_ctx = (*nut_ipmi_ctx_create) ()))
  928. {
  929. @@ -331,6 +359,7 @@ nutscan_device_t * nutscan_scan_ipmi()
  930. return NULL;
  931. }
  932. +fprintf(stdout, "There2\n");
  933. if ((ret = (*nut_ipmi_ctx_find_inband) (ipmi_ctx,
  934. NULL,
  935. 0, /* don't disable auto-probe */
  936. @@ -338,7 +367,7 @@ nutscan_device_t * nutscan_scan_ipmi()
  937. 0,
  938. NULL,
  939. 0, /* workaround flags, none by default */
  940. - 0 /* flags */
  941. + IPMI_FLAGS_NONBLOCKING /* flags */
  942. )) < 0)
  943. {
  944. fprintf(stderr, "ipmi_ctx_find_inband: %s\n",
  945. @@ -350,12 +379,14 @@ nutscan_device_t * nutscan_scan_ipmi()
  946. /* No local IPMI device detected */
  947. return NULL;
  948. }
  949. +fprintf(stdout, "There3 (ret = %i)\n", ret);
  950. /* Loop through all possible components */
  951. for (ipmi_id = 0 ; ipmi_id <= IPMI_FRU_DEVICE_ID_MAX ; ipmi_id++) {
  952. -
  953. +fprintf(stdout, "There4\n");
  954. if (is_ipmi_device_supported(ipmi_ctx, ipmi_id)) {
  955. +fprintf(stdout, "There4.%i\n", ipmi_id);
  956. if ( (nut_dev = nutscan_new_device()) == NULL ) {
  957. fprintf(stderr,"Memory allocation error\n");
  958. nutscan_free_device(current_nut_dev);
  959. --
  960. 1.7.10.2
  961. From 64add831fe9cd779f125f52782c4c58cbd62d64b Mon Sep 17 00:00:00 2001
  962. From: Arnaud Quette <arnaud.quette@free.fr>
  963. Date: Thu, 4 Oct 2012 22:50:52 +0000
  964. Subject: [PATCH] Support power supplies scan over the network
  965. nut-scanner can now scan for power supplies with IPMI over LAN. This is
  966. currently limited to IPMI 1.5 only
  967. Fossil-ID: SVN r3739
  968. ---
  969. docs/man/nut-scanner.txt | 108 +++++++++--------
  970. drivers/nut-ipmipsu.c | 15 ++-
  971. tools/nut-scanner/nut-scan.h | 39 ++++++-
  972. tools/nut-scanner/nut-scanner.c | 74 +++++++++++-
  973. tools/nut-scanner/scan_ipmi.c | 243 ++++++++++++++++++++++++++++++++++-----
  974. 5 files changed, 388 insertions(+), 91 deletions(-)
  975. diff --git a/docs/man/nut-scanner.txt b/docs/man/nut-scanner.txt
  976. index 6948449..efe0e58 100644
  977. --- a/docs/man/nut-scanner.txt
  978. +++ b/docs/man/nut-scanner.txt
  979. @@ -36,118 +36,128 @@ DISPLAY OPTIONS
  980. ---------------
  981. *-N* | *--disp_nut_conf*::
  982. -
  983. - Display result in the 'ups.conf' format.
  984. +Display result in the 'ups.conf' format.
  985. *-P* | *--disp_parsable*::
  986. -
  987. - Display result in a parsable format.
  988. +Display result in a parsable format.
  989. BUS OPTIONS
  990. -----------
  991. *-C* | *--complete_scan*::
  992. -
  993. - Scan all available communication buses (default behavior)
  994. +Scan all available communication buses (default behavior)
  995. *-U* | *--usb_scan*::
  996. -
  997. - List all NUT-compatible USB devices currently plugged in.
  998. +List all NUT-compatible USB devices currently plugged in.
  999. *-S* | *--snmp_scan*::
  1000. -
  1001. - Scan SNMP devices. Requires at least a 'start IP', and optionally, an 'end IP'. See specific SNMP OPTIONS for community and security settings.
  1002. +Scan SNMP devices. Requires at least a 'start IP', and optionally, an 'end IP'. See specific SNMP OPTIONS for community and security settings.
  1003. *-M* | *--xml_scan*::
  1004. -
  1005. - Scan XML/HTTP devices. Broadcast a network message on the current network interfaces to retrieve XML/HTTP capable devices. No IP required.
  1006. +Scan XML/HTTP devices. Broadcast a network message on the current network interfaces to retrieve XML/HTTP capable devices. No IP required.
  1007. *-O* | *--oldnut_scan*::
  1008. -
  1009. - Scan NUT devices (i.e. upsd daemon) on IP ranging from 'start IP' to 'end IP'.
  1010. +Scan NUT devices (i.e. upsd daemon) on IP ranging from 'start IP' to 'end IP'.
  1011. *-A* | *--avahi_scan*::
  1012. -
  1013. - Scan NUT servers using Avahi request on the current network interfaces. No IP required.
  1014. +Scan NUT servers using Avahi request on the current network interfaces. No IP required.
  1015. *-I* | *--ipmi_scan*::
  1016. -
  1017. - Scan NUT compatible devices available via IPMI on the current host.
  1018. +Scan NUT compatible power supplies available via IPMI on the current host, or over the network.
  1019. NETWORK OPTIONS
  1020. ---------------
  1021. *-t* | *--timeout* 'timeout'::
  1022. -
  1023. - Set the network timeout in seconds. Default timeout is 5 seconds.
  1024. +Set the network timeout in seconds. Default timeout is 5 seconds.
  1025. *-s* | *--start_ip* 'start IP'::
  1026. -
  1027. - Set the first IP (IPv4 or IPv6) when a range of IP is required (SNMP, old_nut).
  1028. +Set the first IP (IPv4 or IPv6) when a range of IP is required (SNMP, old_nut).
  1029. *-e* | *--end_ip* 'end IP'::
  1030. -
  1031. - 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.
  1032. +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.
  1033. *-m* | *--mask_cidr* 'IP address/mask'::
  1034. -
  1035. - Set a range of IP using CIDR notation.
  1036. +Set a range of IP using CIDR notation.
  1037. NUT DEVICE OPTION
  1038. -----------------
  1039. *-p* | *--port* 'port number'::
  1040. -
  1041. - Set the port number of scanned NUT devices (default 3493).
  1042. +Set the port number of scanned NUT devices (default 3493).
  1043. SNMP V1 OPTION
  1044. --------------
  1045. *-c* | *--community* 'community'::
  1046. -
  1047. - Set SNMP v1 community name (default = public).
  1048. +Set SNMP v1 community name (default = public).
  1049. SNMP V3 OPTIONS
  1050. ---------------
  1051. *-l* | *--secLevel* 'security level'::
  1052. -
  1053. - Set the 'security level' used for SNMPv3 messages. Allowed values are: noAuthNoPriv, authNoPriv and authPriv.
  1054. +Set the 'security level' used for SNMPv3 messages. Allowed values are: noAuthNoPriv, authNoPriv and authPriv.
  1055. *-u* | *--secName* 'security name'::
  1056. -
  1057. - Set the 'security name' used for authenticated SNMPv3 messages. This parameter is mandatory if you set 'security level'.
  1058. +Set the 'security name' used for authenticated SNMPv3 messages. This parameter is mandatory if you set 'security level'.
  1059. *-w* | *--authProtocol* 'authentication protocol'::
  1060. -
  1061. - Set the 'authentication protocol' used for authenticated SNMPv3 messages. Allowed values are MD5 or SHA. Default value is MD5.
  1062. +Set the 'authentication protocol' used for authenticated SNMPv3 messages. Allowed values are MD5 or SHA. Default value is MD5.
  1063. *-W* | *--authPassword* 'authentication pass phrase'::
  1064. -
  1065. - Set the 'authentication pass phrase' used for authenticated SNMPv3 messages. This parameter is mandatory if you set 'security level' to authNoPriv or authPriv.
  1066. +Set the 'authentication pass phrase' used for authenticated SNMPv3 messages. This parameter is mandatory if you set 'security level' to authNoPriv or authPriv.
  1067. *-x* | *--privProtocol* 'privacy protocol'::
  1068. -
  1069. - Set the 'privacy protocol' used for encrypted SNMPv3 messages. Allowed values are DES or AES. Default value is DES.
  1070. +Set the 'privacy protocol' used for encrypted SNMPv3 messages. Allowed values are DES or AES. Default value is DES.
  1071. *-X* | *--privPassword* 'privacy pass phrase'::
  1072. +Set the 'privacy pass phrase' used for encrypted SNMPv3 messages. This parameter is mandatory if you set 'security level' to authPriv.
  1073. - Set the 'privacy pass phrase' used for encrypted SNMPv3 messages. This parameter is mandatory if you set 'security level' to authPriv.
  1074. +IPMI OPTIONS
  1075. +------------
  1076. +
  1077. +*-b* | *--username* 'username'::
  1078. +Set the username used for authenticating IPMI over LAN connections (mandatory for IPMI over LAN. No default).
  1079. +
  1080. +*-B* | *--password* 'password'::
  1081. +Specify the password to use when authenticationg with the remote host (mandatory for IPMI over LAN. No default).
  1082. +
  1083. +*-d* | *--authType* 'authentication type'::
  1084. +Specify the IPMI 1.5 authentication type to use (NONE, STRAIGHT_PASSWORD_KEY, MD2, and MD5) with the remote host (default=MD5).
  1085. +This forces connection through the 'lan' IPMI interface , thus in IPMI 1.5 mode.
  1086. +
  1087. +*-D* | *--cipher_suite_id* 'cipher suite identifier'::
  1088. +Specify the IPMI 2.0 cipher suite ID to use. The Cipher Suite ID identifies a set of authentication, integrity, and
  1089. +confidentiality algorithms to use for IPMI 2.0 communication. The authentication algorithm identifies the algorithm
  1090. +to use for session setup, the integrity algorithm identifies the algorithm to use for session packet signatures, and the
  1091. +confidentiality algorithm identifies the algorithm to use for payload encryption (default=3).
  1092. ++
  1093. +The following cipher suite ids are currently supported (Authentication; Integrity; Confidentiality):
  1094. +
  1095. +- *0*: None; None; None
  1096. +- *1*: HMAC-SHA1; None; None
  1097. +- *2*: HMAC-SHA1; HMAC-SHA1-96; None
  1098. +- *3*: HMAC-SHA1; HMAC-SHA1-96; AES-CBC-128
  1099. +- *6*: HMAC-MD5; None; None
  1100. +- *7*: HMAC-MD5; HMAC-MD5-128; None
  1101. +- *8*: HMAC-MD5; HMAC-MD5-128; AES-CBC-128
  1102. +- *11*: HMAC-MD5; MD5-128; None
  1103. +- *12*: HMAC-MD5; MD5-128; AES-CBC-128
  1104. +- *15*: HMAC-SHA256; None; None
  1105. +- *16*: HMAC-SHA256; HMAC_SHA256_128; None
  1106. +- *17*: HMAC-SHA256; HMAC_SHA256_128; AES-CBC-128
  1107. MISCELLANEOUS OPTIONS
  1108. ---------------------
  1109. *-V* | *--version*::
  1110. -
  1111. - Display NUT version.
  1112. +Display NUT version.
  1113. *-a* | *--available*::
  1114. -
  1115. - Display available bus that can be scanned , depending on how the binary has been compiled. (OLDNUT, USB, SNMP, XML, AVAHI, IPMI).
  1116. +Display available bus that can be scanned , depending on how the binary has been compiled. (OLDNUT, USB, SNMP, XML, AVAHI, IPMI).
  1117. *-q* | *--quiet*::
  1118. -
  1119. - Display only scan result. No information on currently scanned bus is displayed.
  1120. +Display only scan result. No information on currently scanned bus is displayed.
  1121. EXAMPLES
  1122. --------
  1123. @@ -168,6 +178,10 @@ To scan NUT servers with a timeout of 10 seconds on IP range 192.168.0.0 to 192.
  1124. *nut-scanner -O -t 10 -m 192.168.0.0/25*
  1125. +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:
  1126. +
  1127. +*nut-scanner -I -m 192.168.0.0/24 -b username -B password*
  1128. +
  1129. SEE ALSO
  1130. --------
  1131. diff --git a/drivers/nut-ipmipsu.c b/drivers/nut-ipmipsu.c
  1132. index b7382a8..2991cfc 100644
  1133. --- a/drivers/nut-ipmipsu.c
  1134. +++ b/drivers/nut-ipmipsu.c
  1135. @@ -27,7 +27,7 @@
  1136. #include "nut-ipmi.h"
  1137. #define DRIVER_NAME "IPMI PSU driver"
  1138. -#define DRIVER_VERSION "0.07"
  1139. +#define DRIVER_VERSION "0.30"
  1140. /* driver description structure */
  1141. upsdrv_info_t upsdrv_info = {
  1142. @@ -183,17 +183,20 @@ void upsdrv_makevartable(void)
  1143. "Type of the device to match ('psu' for \"Power Supply\")");
  1144. addvar(VAR_VALUE, "serial", "Serial number to match a specific device");
  1145. - addvar(VAR_VALUE, "fruid", "FRU identifier to match a specific device");
  1146. - addvar(VAR_VALUE, "sensorid", "Sensor identifier to match a specific device"); */
  1147. + addvar(VAR_VALUE, "fruid", "FRU identifier to match a specific device"); */
  1148. }
  1149. void upsdrv_initups(void)
  1150. {
  1151. upsdebugx(1, "upsdrv_initups...");
  1152. - /* port can be expressed using:
  1153. - * "id?" for device (FRU) ID 0x?
  1154. - * "psu?" for PSU number ?
  1155. + /* port can be expressed in various forms:
  1156. + * - inband:
  1157. + * "id?" for device (FRU) ID 0x?
  1158. + * "psu?" for PSU number ?
  1159. + * - out of band
  1160. + * "id?@host"
  1161. + * "host" => requires serial or ...
  1162. */
  1163. if (!strncmp( device_path, "id", 2))
  1164. {
  1165. diff --git a/tools/nut-scanner/nut-scan.h b/tools/nut-scanner/nut-scan.h
  1166. index affcc77..8b9f1ab 100644
  1167. --- a/tools/nut-scanner/nut-scan.h
  1168. +++ b/tools/nut-scanner/nut-scan.h
  1169. @@ -1,6 +1,8 @@
  1170. /* nut-scan.h: detect NUT services
  1171. *
  1172. - * Copyright (C) 2011 - Frederic Bohe <fredericbohe@eaton.com>
  1173. + * Copyright (C)
  1174. + * 2011 - Frederic Bohe <fredericbohe@eaton.com>
  1175. + * 2012 - Arnaud Quette <arnaud.quette@free.fr>
  1176. *
  1177. * This program is free software; you can redistribute it and/or modify
  1178. * it under the terms of the GNU General Public License as published by
  1179. @@ -16,6 +18,7 @@
  1180. * along with this program; if not, write to the Free Software
  1181. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  1182. */
  1183. +
  1184. #ifndef NUT_SCAN_H
  1185. #define NUT_SCAN_H
  1186. @@ -23,6 +26,10 @@
  1187. #include <nutscan-device.h>
  1188. #include <nutscan-ip.h>
  1189. +#ifdef WITH_IPMI
  1190. +#include <freeipmi/freeipmi.h>
  1191. +#endif
  1192. +
  1193. /* SNMP structure */
  1194. typedef struct nutscan_snmp {
  1195. char * community;
  1196. @@ -36,8 +43,34 @@ typedef struct nutscan_snmp {
  1197. void * handle;
  1198. } nutscan_snmp_t;
  1199. +/* IPMI structure */
  1200. +/* Settings for OutofBand (remote) connection */
  1201. +typedef struct nutscan_ipmi {
  1202. + char* username; /* IPMI 1.5 and 2.0 */
  1203. + char* password; /* IPMI 1.5 and 2.0 */
  1204. + int authentication_type; /* IPMI 1.5 */
  1205. + int cipher_suite_id; /* IPMI 2.0 */
  1206. + char* K_g_BMC_key; /* IPMI 2.0, optional key for 2 key auth. */
  1207. + int privilege_level; /* for both */
  1208. + unsigned int workaround_flags; /* for both */
  1209. + int ipmi_version; /* IPMI 1.5 or 2.0? */
  1210. +} nutscan_ipmi_t;
  1211. +
  1212. +/* IPMI auth defines, simply using FreeIPMI defines */
  1213. +#ifndef IPMI_AUTHENTICATION_TYPE_NONE
  1214. + #define IPMI_AUTHENTICATION_TYPE_NONE 0x00
  1215. + #define IPMI_AUTHENTICATION_TYPE_MD2 0x01
  1216. + #define IPMI_AUTHENTICATION_TYPE_MD5 0x02
  1217. + #define IPMI_AUTHENTICATION_TYPE_STRAIGHT_PASSWORD_KEY 0x04
  1218. + #define IPMI_AUTHENTICATION_TYPE_OEM_PROP 0x05
  1219. + #define IPMI_AUTHENTICATION_TYPE_RMCPPLUS 0x06
  1220. +#endif /* IPMI_AUTHENTICATION_TYPE_NONE */
  1221. +
  1222. +#define IPMI_1_5 1
  1223. +#define IPMI_2_0 0
  1224. +
  1225. /* Scanning */
  1226. -nutscan_device_t * nutscan_scan_snmp(const char * start_ip,const char * stop_ip,long usec_timeout, nutscan_snmp_t * sec);
  1227. +nutscan_device_t * nutscan_scan_snmp(const char * start_ip, const char * stop_ip, long usec_timeout, nutscan_snmp_t * sec);
  1228. nutscan_device_t * nutscan_scan_usb();
  1229. @@ -47,7 +80,7 @@ nutscan_device_t * nutscan_scan_nut(const char * startIP, const char * stopIP, c
  1230. nutscan_device_t * nutscan_scan_avahi(long usec_timeout);
  1231. -nutscan_device_t * nutscan_scan_ipmi(void);
  1232. +nutscan_device_t * nutscan_scan_ipmi(const char * startIP, const char * stopIP, nutscan_ipmi_t * sec);
  1233. /* Display functions */
  1234. void nutscan_display_ups_conf(nutscan_device_t * device);
  1235. diff --git a/tools/nut-scanner/nut-scanner.c b/tools/nut-scanner/nut-scanner.c
  1236. index 52e0da7..7ca1554 100644
  1237. --- a/tools/nut-scanner/nut-scanner.c
  1238. +++ b/tools/nut-scanner/nut-scanner.c
  1239. @@ -35,7 +35,7 @@
  1240. #define ERR_BAD_OPTION (-1)
  1241. -const char optstring[] = "?ht:s:e:c:l:u:W:X:w:x:p:CUSMOAm:NPqIVa";
  1242. +const char optstring[] = "?ht:s:e:c:l:u:W:X:w:x:p:b:B:d:D:CUSMOAm:NPqIVa";
  1243. #ifdef HAVE_GETOPT_LONG
  1244. const struct option longopts[] =
  1245. @@ -50,6 +50,10 @@ const struct option longopts[] =
  1246. { "privPassword",required_argument,NULL,'X' },
  1247. { "authProtocol",required_argument,NULL,'w' },
  1248. { "privProtocol",required_argument,NULL,'x' },
  1249. + { "username",required_argument,NULL,'b' },
  1250. + { "password",required_argument,NULL,'B' },
  1251. + { "authType",required_argument,NULL,'d' },
  1252. + { "cipher_suite_id",required_argument,NULL,'D' },
  1253. { "port",required_argument,NULL,'p' },
  1254. { "complete_scan",no_argument,NULL,'C' },
  1255. { "usb_scan",no_argument,NULL,'U' },
  1256. @@ -110,7 +114,9 @@ static void * run_avahi(void * arg)
  1257. }
  1258. static void * run_ipmi(void * arg)
  1259. {
  1260. - dev[TYPE_IPMI] = nutscan_scan_ipmi();
  1261. + nutscan_ipmi_t * sec = (nutscan_ipmi_t *)arg;
  1262. +
  1263. + dev[TYPE_IPMI] = nutscan_scan_ipmi(start_ip,end_ip,sec);
  1264. return NULL;
  1265. }
  1266. #endif /* HAVE_PTHREAD */
  1267. @@ -133,6 +139,7 @@ static int printq(int quiet,const char *fmt, ...)
  1268. int main(int argc, char *argv[])
  1269. {
  1270. nutscan_snmp_t snmp_sec;
  1271. + nutscan_ipmi_t ipmi_sec;
  1272. int opt_ret;
  1273. char * cidr = NULL;
  1274. int allow_all = 0;
  1275. @@ -147,6 +154,12 @@ int main(int argc, char *argv[])
  1276. int ret_code = EXIT_SUCCESS;
  1277. memset(&snmp_sec, 0, sizeof(snmp_sec));
  1278. + memset(&ipmi_sec, 0, sizeof(ipmi_sec));
  1279. + /* Set the default values for IPMI */
  1280. + ipmi_sec.authentication_type = IPMI_AUTHENTICATION_TYPE_MD5;
  1281. + ipmi_sec.ipmi_version = IPMI_1_5; /* default to IPMI 1.5, if not otherwise specified */
  1282. + ipmi_sec.cipher_suite_id = 3; /* default to HMAC-SHA1; HMAC-SHA1-96; AES-CBC-128 */
  1283. + ipmi_sec.privilege_level = IPMI_PRIVILEGE_LEVEL_ADMIN; /* should be sufficient */
  1284. nutscan_init();
  1285. @@ -220,6 +233,45 @@ int main(int argc, char *argv[])
  1286. }
  1287. allow_snmp = 1;
  1288. break;
  1289. + case 'b':
  1290. + if(!nutscan_avail_ipmi) {
  1291. + goto display_help;
  1292. + }
  1293. + ipmi_sec.username = strdup(optarg);
  1294. + break;
  1295. + case 'B':
  1296. + if(!nutscan_avail_ipmi) {
  1297. + goto display_help;
  1298. + }
  1299. + ipmi_sec.password = strdup(optarg);
  1300. + break;
  1301. + case 'd':
  1302. + if(!nutscan_avail_ipmi) {
  1303. + goto display_help;
  1304. + }
  1305. + if (!strcmp(optarg, "NONE")) {
  1306. + ipmi_sec.authentication_type = IPMI_AUTHENTICATION_TYPE_NONE;
  1307. + }
  1308. + else if (!strcmp(optarg, "STRAIGHT_PASSWORD_KEY")) {
  1309. + ipmi_sec.authentication_type = IPMI_AUTHENTICATION_TYPE_STRAIGHT_PASSWORD_KEY;
  1310. + }
  1311. + else if (!strcmp(optarg, "MD2")) {
  1312. + ipmi_sec.authentication_type = IPMI_AUTHENTICATION_TYPE_MD2;
  1313. + }
  1314. + else if (!strcmp(optarg, "MD5")) {
  1315. + ipmi_sec.authentication_type = IPMI_AUTHENTICATION_TYPE_MD5;
  1316. + }
  1317. + else {
  1318. + fprintf(stderr,"Unknown authentication type (%s). Defaulting to MD5\n", optarg);
  1319. + }
  1320. + break;
  1321. + case 'D':
  1322. + if(!nutscan_avail_ipmi) {
  1323. + goto display_help;
  1324. + }
  1325. + ipmi_sec.cipher_suite_id = atoi(optarg);
  1326. + /* Force IPMI 2.0! */
  1327. + ipmi_sec.ipmi_version = IPMI_2_0;
  1328. case 'p':
  1329. port = strdup(optarg);
  1330. break;
  1331. @@ -307,6 +359,8 @@ display_help:
  1332. if( nutscan_avail_ipmi ) {
  1333. printf(" -I, --ipmi_scan: Scan IPMI devices.\n");
  1334. }
  1335. +
  1336. + printf("\nNetwork specific options:\n");
  1337. printf(" -t, --timeout <timeout in seconds>: network operation timeout (default %d).\n",DEFAULT_TIMEOUT);
  1338. printf(" -s, --start_ip <IP address>: First IP address to scan.\n");
  1339. printf(" -e, --end_ip <IP address>: Last IP address to scan.\n");
  1340. @@ -325,6 +379,18 @@ display_help:
  1341. printf(" -X, --privPassword <privacy pass phrase>: Set the privacy pass phrase used for encrypted SNMPv3 messages (mandatory if you set secLevel to authPriv)\n");
  1342. }
  1343. + if( nutscan_avail_ipmi ) {
  1344. + printf("\nIPMI over LAN specific options:\n");
  1345. + printf(" -b, --username <username>: Set the username used for authenticating IPMI over LAN connections (mandatory for IPMI over LAN. No default)\n");
  1346. + /* 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
  1347. + * at least ADMIN privileges in order for this tool to operate fully. */
  1348. + printf(" -B, --password <password>: Specify the password to use when authenticationg with the remote host (mandatory for IPMI over LAN. No default)\n");
  1349. + /* 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
  1350. + * 1.5 and 20 for IPMI 2.0. */
  1351. + 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");
  1352. + 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");
  1353. + }
  1354. +
  1355. printf("\nNUT specific options:\n");
  1356. printf(" -p, --port <port number>: Port number of remote NUT upsd\n");
  1357. printf("\ndisplay specific options:\n");
  1358. @@ -427,11 +493,11 @@ display_help:
  1359. if( allow_ipmi && nutscan_avail_ipmi) {
  1360. printq(quiet,"Scanning IPMI bus.\n");
  1361. #ifdef HAVE_PTHREAD
  1362. - if(pthread_create(&thread[TYPE_IPMI],NULL,run_ipmi,NULL)) {
  1363. + if(pthread_create(&thread[TYPE_IPMI],NULL,run_ipmi,&ipmi_sec)) {
  1364. nutscan_avail_ipmi = 0;
  1365. }
  1366. #else
  1367. - dev[TYPE_IPMI] = nutscan_scan_ipmi();
  1368. + dev[TYPE_IPMI] = nutscan_scan_ipmi(start_ip,end_ip,timeout,&ipmi_sec);
  1369. #endif /* HAVE_PTHREAD */
  1370. }
  1371. diff --git a/tools/nut-scanner/scan_ipmi.c b/tools/nut-scanner/scan_ipmi.c
  1372. index c1ec78a..0288ad4 100644
  1373. --- a/tools/nut-scanner/scan_ipmi.c
  1374. +++ b/tools/nut-scanner/scan_ipmi.c
  1375. @@ -29,6 +29,11 @@
  1376. #define NUT_IPMI_DRV_NAME "nut-ipmipsu"
  1377. +/* IPMI defines */
  1378. +/* 5 seconds for establishing an IPMI connection */
  1379. +#define IPMI_SESSION_TIMEOUT_LENGTH_DEFAULT 5000
  1380. +#define IPMI_RETRANSMISSION_TIMEOUT_LENGTH_DEFAULT 250
  1381. +
  1382. /* dynamic link library stuff */
  1383. static char * libname = "libfreeipmi";
  1384. static lt_dlhandle dl_handle = NULL;
  1385. @@ -88,10 +93,23 @@ static int (*nut_ipmi_ctx_find_inband) (ipmi_ctx_t ctx,
  1386. const char *driver_device,
  1387. unsigned int workaround_flags,
  1388. unsigned int flags);
  1389. +static int (*nut_ipmi_ctx_open_outofband) (ipmi_ctx_t ctx,
  1390. + const char *hostname,
  1391. + const char *username,
  1392. + const char *password,
  1393. + uint8_t authentication_type,
  1394. + uint8_t privilege_level,
  1395. + unsigned int session_timeout,
  1396. + unsigned int retransmission_timeout,
  1397. + unsigned int workaround_flags,
  1398. + unsigned int flags);
  1399. +static int (*nut_ipmi_ctx_errnum) (ipmi_ctx_t ctx);
  1400. static char * (*nut_ipmi_ctx_errormsg) (ipmi_ctx_t ctx);
  1401. static int (*nut_ipmi_ctx_close) (ipmi_ctx_t ctx);
  1402. static void (*nut_ipmi_ctx_destroy) (ipmi_ctx_t ctx);
  1403. +/* Internal functions */
  1404. +static nutscan_device_t * nutscan_scan_ipmi_device(const char * IPaddr, nutscan_ipmi_t * sec);
  1405. /* Return 0 on error */
  1406. int nutscan_load_ipmi_library()
  1407. @@ -189,6 +207,16 @@ int nutscan_load_ipmi_library()
  1408. goto err;
  1409. }
  1410. + *(void **) (&nut_ipmi_ctx_open_outofband) = lt_dlsym(dl_handle, "ipmi_ctx_open_outofband");
  1411. + if ((dl_error = lt_dlerror()) != NULL) {
  1412. + goto err;
  1413. + }
  1414. +
  1415. + *(void **) (&nut_ipmi_ctx_errnum) = lt_dlsym(dl_handle, "ipmi_ctx_errnum");
  1416. + if ((dl_error = lt_dlerror()) != NULL) {
  1417. + goto err;
  1418. + }
  1419. +
  1420. *(void **) (&nut_ipmi_ctx_errormsg) = lt_dlsym(dl_handle, "ipmi_ctx_errormsg");
  1421. if ((dl_error = lt_dlerror()) != NULL) {
  1422. goto err;
  1423. @@ -265,10 +293,10 @@ int is_ipmi_device_supported(ipmi_ctx_t ipmi_ctx, int ipmi_id)
  1424. /* Parse FRU information */
  1425. if (!(fru_parse_ctx = (*nut_ipmi_fru_ctx_create) (ipmi_ctx)))
  1426. {
  1427. - fprintf(stderr, "ipmi_fru_parse_ctx_create()\n");
  1428. + fprintf(stderr, "Error with %s(): %s\n", IPMI_FRU_CTX_CREATE, (*nut_ipmi_ctx_errormsg)(ipmi_ctx));
  1429. return 0;
  1430. }
  1431. -fprintf(stdout, "There.1\n");
  1432. +
  1433. /* lots of motherboards calculate checksums incorrectly */
  1434. if ((*nut_ipmi_fru_ctx_set_flags) (fru_parse_ctx, IPMI_FRU_FLAGS_SKIP_CHECKSUM_CHECKS) < 0)
  1435. {
  1436. @@ -279,7 +307,7 @@ fprintf(stdout, "There.1\n");
  1437. #endif /* HAVE_FREEIPMI_11X_12X */
  1438. return 0;
  1439. }
  1440. -fprintf(stdout, "There.2\n");
  1441. +
  1442. if ((*nut_ipmi_fru_open_device_id) (fru_parse_ctx, ipmi_id) < 0)
  1443. {
  1444. #ifdef HAVE_FREEIPMI_11X_12X
  1445. @@ -292,7 +320,6 @@ fprintf(stdout, "There.2\n");
  1446. do
  1447. {
  1448. -fprintf(stdout, "There.3\n");
  1449. /* clear fields */
  1450. area_type = 0;
  1451. area_length = 0;
  1452. @@ -337,20 +364,21 @@ fprintf(stdout, "There.3\n");
  1453. return 0;
  1454. }
  1455. -/* return NULL on error */
  1456. -nutscan_device_t * nutscan_scan_ipmi()
  1457. +/* Check for IPMI support on a specific (local or remote) system
  1458. + * Return NULL on error, or a valid nutscan_device_t otherwise */
  1459. +nutscan_device_t * nutscan_scan_ipmi_device(const char * IPaddr, nutscan_ipmi_t * ipmi_sec)
  1460. {
  1461. ipmi_ctx_t ipmi_ctx = NULL;
  1462. nutscan_device_t * nut_dev = NULL;
  1463. nutscan_device_t * current_nut_dev = NULL;
  1464. int ret = -1;
  1465. int ipmi_id = 0;
  1466. - char port_id[10];
  1467. + char port_id[64];
  1468. if( !nutscan_avail_ipmi ) {
  1469. return NULL;
  1470. }
  1471. -fprintf(stdout, "There1\n");
  1472. +
  1473. /* Initialize the FreeIPMI library. */
  1474. if (!(ipmi_ctx = (*nut_ipmi_ctx_create) ()))
  1475. {
  1476. @@ -359,34 +387,138 @@ fprintf(stdout, "There1\n");
  1477. return NULL;
  1478. }
  1479. -fprintf(stdout, "There2\n");
  1480. - if ((ret = (*nut_ipmi_ctx_find_inband) (ipmi_ctx,
  1481. - NULL,
  1482. - 0, /* don't disable auto-probe */
  1483. - 0,
  1484. - 0,
  1485. - NULL,
  1486. - 0, /* workaround flags, none by default */
  1487. - IPMI_FLAGS_NONBLOCKING /* flags */
  1488. - )) < 0)
  1489. + /* Are we scanning locally, or over the network? */
  1490. + if (IPaddr == NULL)
  1491. {
  1492. - fprintf(stderr, "ipmi_ctx_find_inband: %s\n",
  1493. - (*nut_ipmi_ctx_errormsg) (ipmi_ctx));
  1494. - return NULL;
  1495. + /* FIXME: we need root right to access local IPMI!
  1496. + if (!ipmi_is_root ()) {
  1497. + fprintf(stderr, "IPMI scan: %s\n", ipmi_ctx_strerror (IPMI_ERR_PERMISSION));
  1498. + } */
  1499. +
  1500. + if ((ret = (*nut_ipmi_ctx_find_inband) (ipmi_ctx,
  1501. + NULL,
  1502. + 0, /* don't disable auto-probe */
  1503. + 0,
  1504. + 0,
  1505. + NULL,
  1506. + 0, /* workaround flags, none by default */
  1507. + 0 /* flags */
  1508. + )) < 0)
  1509. + {
  1510. + fprintf(stderr, "ipmi_ctx_find_inband: %s\n",
  1511. + (*nut_ipmi_ctx_errormsg) (ipmi_ctx));
  1512. + return NULL;
  1513. + }
  1514. + if (!ret)
  1515. + {
  1516. + /* No local IPMI device detected */
  1517. + return NULL;
  1518. + }
  1519. }
  1520. - if (!ret)
  1521. - {
  1522. - /* No local IPMI device detected */
  1523. - return NULL;
  1524. + else {
  1525. +
  1526. +#if 0
  1527. + if (ipmi_sec->ipmi_version == IPMI_2_0) {
  1528. +
  1529. + /* FIXME: need processing?!
  1530. + * int parse_kg (void *out, unsigned int outlen, const char *in)
  1531. + * if ((rv = parse_kg (common_cmd_args_config->k_g, IPMI_MAX_K_G_LENGTH + 1, data->string)) < 0)
  1532. + * {
  1533. + * fprintf (stderr, "Config File Error: k_g input formatted incorrectly\n");
  1534. + * exit (EXIT_FAILURE);
  1535. + * }*/
  1536. + if ((ret = (*nut_ipmi_ctx_open_outofband_2_0) (ipmi_ctx,
  1537. + IPaddr,
  1538. + ipmi_sec->username,
  1539. + ipmi_sec->password,
  1540. + ipmi_sec->K_g_BMC_key,
  1541. +??? (ipmi_sec->K_g_BMC_key) ? config->k_g_len : 0,
  1542. + ipmi_sec->privilege_level,
  1543. + ipmi_sec->cipher_suite_id,
  1544. + IPMI_SESSION_TIMEOUT_LENGTH_DEFAULT,
  1545. + IPMI_RETRANSMISSION_TIMEOUT_LENGTH_DEFAULT,
  1546. + ipmi_dev->workaround_flags,
  1547. + flags) < 0)
  1548. + {
  1549. + IPMI_MONITORING_DEBUG (("ipmi_ctx_open_outofband_2_0: %s", ipmi_ctx_errormsg (c->ipmi_ctx)));
  1550. + if (ipmi_ctx_errnum (c->ipmi_ctx) == IPMI_ERR_USERNAME_INVALID)
  1551. + c->errnum = IPMI_MONITORING_ERR_USERNAME_INVALID;
  1552. + else if (ipmi_ctx_errnum (c->ipmi_ctx) == IPMI_ERR_PASSWORD_INVALID)
  1553. + c->errnum = IPMI_MONITORING_ERR_PASSWORD_INVALID;
  1554. + else if (ipmi_ctx_errnum (c->ipmi_ctx) == IPMI_ERR_PRIVILEGE_LEVEL_INSUFFICIENT)
  1555. + c->errnum = IPMI_MONITORING_ERR_PRIVILEGE_LEVEL_INSUFFICIENT;
  1556. + else if (ipmi_ctx_errnum (c->ipmi_ctx) == IPMI_ERR_PRIVILEGE_LEVEL_CANNOT_BE_OBTAINED)
  1557. + c->errnum = IPMI_MONITORING_ERR_PRIVILEGEL_LEVEL_CANNOT_BE_OBTAINED;
  1558. + else if (ipmi_ctx_errnum (c->ipmi_ctx) == IPMI_ERR_K_G_INVALID)
  1559. + c->errnum = IPMI_MONITORING_ERR_K_G_INVALID;
  1560. + else if (ipmi_ctx_errnum (c->ipmi_ctx) == IPMI_ERR_CIPHER_SUITE_ID_UNAVAILABLE)
  1561. + c->errnum = IPMI_MONITORING_ERR_CIPHER_SUITE_ID_UNAVAILABLE;
  1562. + else if (ipmi_ctx_errnum (c->ipmi_ctx) == IPMI_ERR_PASSWORD_VERIFICATION_TIMEOUT)
  1563. + c->errnum = IPMI_MONITORING_ERR_PASSWORD_VERIFICATION_TIMEOUT;
  1564. + else if (ipmi_ctx_errnum (c->ipmi_ctx) == IPMI_ERR_IPMI_2_0_UNAVAILABLE)
  1565. + c->errnum = IPMI_MONITORING_ERR_IPMI_2_0_UNAVAILABLE;
  1566. + else if (ipmi_ctx_errnum (c->ipmi_ctx) == IPMI_ERR_CONNECTION_TIMEOUT)
  1567. + c->errnum = IPMI_MONITORING_ERR_CONNECTION_TIMEOUT;
  1568. + else if (ipmi_ctx_errnum (c->ipmi_ctx) == IPMI_ERR_SESSION_TIMEOUT)
  1569. + c->errnum = IPMI_MONITORING_ERR_SESSION_TIMEOUT;
  1570. + else if (ipmi_ctx_errnum (c->ipmi_ctx) == IPMI_ERR_BAD_COMPLETION_CODE
  1571. + || ipmi_ctx_errnum (c->ipmi_ctx) == IPMI_ERR_IPMI_ERROR)
  1572. + c->errnum = IPMI_MONITORING_ERR_IPMI_ERROR;
  1573. + else if (ipmi_ctx_errnum (c->ipmi_ctx) == IPMI_ERR_BMC_BUSY)
  1574. + c->errnum = IPMI_MONITORING_ERR_BMC_BUSY;
  1575. + else if (ipmi_ctx_errnum (c->ipmi_ctx) == IPMI_ERR_OUT_OF_MEMORY)
  1576. + c->errnum = IPMI_MONITORING_ERR_OUT_OF_MEMORY;
  1577. + else if (ipmi_ctx_errnum (c->ipmi_ctx) == IPMI_ERR_HOSTNAME_INVALID)
  1578. + c->errnum = IPMI_MONITORING_ERR_HOSTNAME_INVALID;
  1579. + else if (ipmi_ctx_errnum (c->ipmi_ctx) == IPMI_ERR_PARAMETERS)
  1580. + c->errnum = IPMI_MONITORING_ERR_PARAMETERS;
  1581. + else if (ipmi_ctx_errnum (c->ipmi_ctx) == IPMI_ERR_SYSTEM_ERROR)
  1582. + c->errnum = IPMI_MONITORING_ERR_SYSTEM_ERROR;
  1583. + else
  1584. + c->errnum = IPMI_MONITORING_ERR_INTERNAL_ERROR;
  1585. + return (-1);
  1586. + }
  1587. + }
  1588. + else { /* Not IPMI 2.0 */
  1589. +
  1590. +#endif /* 0 */
  1591. +
  1592. + /* Fall back to IPMI 1.5 */
  1593. + if ((ret = (*nut_ipmi_ctx_open_outofband) (ipmi_ctx,
  1594. + IPaddr,
  1595. + ipmi_sec->username,
  1596. + ipmi_sec->password,
  1597. + ipmi_sec->authentication_type,
  1598. + ipmi_sec->privilege_level,
  1599. + IPMI_SESSION_TIMEOUT_LENGTH_DEFAULT,
  1600. + IPMI_RETRANSMISSION_TIMEOUT_LENGTH_DEFAULT,
  1601. + ipmi_sec->workaround_flags,
  1602. + IPMI_FLAGS_DEFAULT
  1603. + )) < 0)
  1604. + {
  1605. + /* No IPMI device detected on this host!
  1606. + if ((*nut_ipmi_ctx_errnum) (ipmi_ctx) == IPMI_ERR_USERNAME_INVALID
  1607. + || (*nut_ipmi_ctx_errnum) (ipmi_ctx) == IPMI_ERR_PASSWORD_INVALID
  1608. + || (*nut_ipmi_ctx_errnum) (ipmi_ctx) == IPMI_ERR_PRIVILEGE_LEVEL_INSUFFICIENT
  1609. + || (*nut_ipmi_ctx_errnum) (ipmi_ctx) == IPMI_ERR_PRIVILEGE_LEVEL_CANNOT_BE_OBTAINED
  1610. + || (*nut_ipmi_ctx_errnum) (ipmi_ctx) == IPMI_ERR_AUTHENTICATION_TYPE_UNAVAILABLE
  1611. + || (*nut_ipmi_ctx_errnum) (ipmi_ctx) == IPMI_ERR_PASSWORD_VERIFICATION_TIMEOUT
  1612. + || (*nut_ipmi_ctx_errnum) (ipmi_ctx) == IPMI_ERR_HOSTNAME_INVALID
  1613. + || (*nut_ipmi_ctx_errnum) (ipmi_ctx) == IPMI_ERR_CONNECTION_TIMEOUT) { */
  1614. +
  1615. + /* FIXME: don't log timeout errors */
  1616. + fprintf(stderr, "nut_ipmi_ctx_open_outofband: %s\n",
  1617. + (*nut_ipmi_ctx_errormsg) (ipmi_ctx));
  1618. + return NULL;
  1619. + /*}*/
  1620. + }
  1621. }
  1622. -fprintf(stdout, "There3 (ret = %i)\n", ret);
  1623. /* Loop through all possible components */
  1624. for (ipmi_id = 0 ; ipmi_id <= IPMI_FRU_DEVICE_ID_MAX ; ipmi_id++) {
  1625. -fprintf(stdout, "There4\n");
  1626. +
  1627. if (is_ipmi_device_supported(ipmi_ctx, ipmi_id)) {
  1628. -fprintf(stdout, "There4.%i\n", ipmi_id);
  1629. if ( (nut_dev = nutscan_new_device()) == NULL ) {
  1630. fprintf(stderr,"Memory allocation error\n");
  1631. nutscan_free_device(current_nut_dev);
  1632. @@ -396,9 +528,17 @@ fprintf(stdout, "There4.%i\n", ipmi_id);
  1633. /* Fill the device structure (sufficient with driver and port) */
  1634. nut_dev->type = TYPE_IPMI;
  1635. nut_dev->driver = strdup(NUT_IPMI_DRV_NAME);
  1636. - sprintf(port_id, "id%x", ipmi_id);
  1637. + if (IPaddr == NULL) {
  1638. + sprintf(port_id, "id%x", ipmi_id);
  1639. + }
  1640. + else {
  1641. + /* FIXME: also check against "localhost" and its IPv{4,6} */
  1642. + sprintf(port_id, "id%x@%s", ipmi_id, IPaddr);
  1643. + }
  1644. nut_dev->port = strdup(port_id);
  1645. -
  1646. + /* FIXME: also dump device.serial?
  1647. + * using drivers/libfreeipmi_get_board_info() */
  1648. +
  1649. current_nut_dev = nutscan_add_device_to_device(
  1650. current_nut_dev,
  1651. nut_dev);
  1652. @@ -415,9 +555,50 @@ fprintf(stdout, "There4.%i\n", ipmi_id);
  1653. return current_nut_dev;
  1654. }
  1655. +
  1656. +/* General IPMI scan entry point: scan 1 to n devices, local or remote,
  1657. + * for IPMI support
  1658. + * Return NULL on error, or a valid nutscan_device_t otherwise */
  1659. +nutscan_device_t * nutscan_scan_ipmi(const char * start_ip, const char * stop_ip, nutscan_ipmi_t * sec)
  1660. +{
  1661. + nutscan_ip_iter_t ip;
  1662. + char * ip_str = NULL;
  1663. + nutscan_ipmi_t * tmp_sec;
  1664. + nutscan_device_t * nut_dev = NULL;
  1665. + nutscan_device_t * current_nut_dev = NULL;
  1666. +
  1667. + if( !nutscan_avail_ipmi ) {
  1668. + return NULL;
  1669. + }
  1670. +
  1671. +
  1672. + /* Are we scanning locally, or through the network? */
  1673. + if (start_ip == NULL)
  1674. + {
  1675. + /* Local PSU scan */
  1676. + current_nut_dev = nutscan_scan_ipmi_device(NULL, NULL);
  1677. + }
  1678. + else {
  1679. + ip_str = nutscan_ip_iter_init(&ip, start_ip, stop_ip);
  1680. +
  1681. + while(ip_str != NULL) {
  1682. + tmp_sec = malloc(sizeof(nutscan_ipmi_t));
  1683. + memcpy(tmp_sec, sec, sizeof(nutscan_ipmi_t));
  1684. +
  1685. + if ((current_nut_dev = nutscan_scan_ipmi_device(ip_str, tmp_sec)) != NULL) {
  1686. + /* Store the positive result */
  1687. + current_nut_dev = nutscan_add_device_to_device(current_nut_dev, nut_dev);
  1688. + }
  1689. + /* Prepare the next iteration */
  1690. + ip_str = nutscan_ip_iter_inc(&ip);
  1691. + };
  1692. + }
  1693. +
  1694. + return current_nut_dev;
  1695. +}
  1696. #else /* WITH_IPMI */
  1697. /* stub function */
  1698. -nutscan_device_t * nutscan_scan_ipmi()
  1699. +nutscan_device_t * nutscan_scan_ipmi(const char * startIP, const char * stopIP, nutscan_ipmi_t * sec)
  1700. {
  1701. return NULL;
  1702. }
  1703. --
  1704. 1.7.10.2
  1705. From 3d0002653a506f2acb24be2201724e7b785de784 Mon Sep 17 00:00:00 2001
  1706. From: Arnaud Quette <arnaud.quette@free.fr>
  1707. Date: Fri, 5 Oct 2012 10:27:55 +0000
  1708. Subject: [PATCH] Fix compilation error
  1709. Define IPMI_PRIVILEGE_LEVEL_ADMIN value, in case FreeIPMI is not
  1710. available
  1711. Fossil-ID: SVN r3741
  1712. ---
  1713. tools/nut-scanner/nut-scan.h | 5 ++++-
  1714. 1 file changed, 4 insertions(+), 1 deletion(-)
  1715. diff --git a/tools/nut-scanner/nut-scan.h b/tools/nut-scanner/nut-scan.h
  1716. index 8b9f1ab..b853d96 100644
  1717. --- a/tools/nut-scanner/nut-scan.h
  1718. +++ b/tools/nut-scanner/nut-scan.h
  1719. @@ -64,7 +64,10 @@ typedef struct nutscan_ipmi {
  1720. #define IPMI_AUTHENTICATION_TYPE_STRAIGHT_PASSWORD_KEY 0x04
  1721. #define IPMI_AUTHENTICATION_TYPE_OEM_PROP 0x05
  1722. #define IPMI_AUTHENTICATION_TYPE_RMCPPLUS 0x06
  1723. -#endif /* IPMI_AUTHENTICATION_TYPE_NONE */
  1724. +#endif
  1725. +#ifndef IPMI_PRIVILEGE_LEVEL_ADMIN
  1726. + #define IPMI_PRIVILEGE_LEVEL_ADMIN 0x04
  1727. +#endif
  1728. #define IPMI_1_5 1
  1729. #define IPMI_2_0 0
  1730. --
  1731. 1.7.10.2
  1732. From 605ef0a46fbb8519b849683028f7e6cf35eb2fdd Mon Sep 17 00:00:00 2001
  1733. From: Arnaud Quette <arnaud.quette@free.fr>
  1734. Date: Thu, 11 Apr 2013 23:15:51 +0200
  1735. Subject: [PATCH] Set USB timeout to 5 seconds
  1736. Set the low level USB timeout back to the standard
  1737. 5 seconds. This was set to 4 seconds, for performance
  1738. reasons, but is now causing issues with some devices
  1739. (reported by Stefan "stevenbg", GitHub issue #23)
  1740. ---
  1741. drivers/libusb.c | 7 +++----
  1742. 1 file changed, 3 insertions(+), 4 deletions(-)
  1743. diff --git a/drivers/libusb.c b/drivers/libusb.c
  1744. index 50bfc7f..234b9f1 100644
  1745. --- a/drivers/libusb.c
  1746. +++ b/drivers/libusb.c
  1747. @@ -33,12 +33,11 @@
  1748. #include "usb-common.h"
  1749. #include "libusb.h"
  1750. -/* USB standard state 5000, but we've decreased it to
  1751. - * improve reactivity */
  1752. -#define USB_TIMEOUT 4000
  1753. +/* USB standard timeout */
  1754. +#define USB_TIMEOUT 5000
  1755. #define USB_DRIVER_NAME "USB communication driver"
  1756. -#define USB_DRIVER_VERSION "0.31"
  1757. +#define USB_DRIVER_VERSION "0.32"
  1758. /* driver description structure */
  1759. upsdrv_info_t comm_upsdrv_info = {
  1760. --
  1761. 1.7.10.2