ipmi_main.c 30 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073
  1. /*
  2. * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. *
  8. * Redistribution of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. *
  11. * Redistribution in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. *
  15. * Neither the name of Sun Microsystems, Inc. or the names of
  16. * contributors may be used to endorse or promote products derived
  17. * from this software without specific prior written permission.
  18. *
  19. * This software is provided "AS IS," without a warranty of any kind.
  20. * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
  21. * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
  22. * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
  23. * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE
  24. * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
  25. * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
  26. * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
  27. * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
  28. * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
  29. * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
  30. * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
  31. */
  32. #define _XOPEN_SOURCE 700
  33. #define _BSD_SOURCE || \
  34. (_XOPEN_SOURCE >= 500 || \
  35. _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED) && \
  36. !(_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600)
  37. #include <stdlib.h>
  38. #include <stdio.h>
  39. #include <inttypes.h>
  40. #include <signal.h>
  41. #include <string.h>
  42. #include <strings.h>
  43. #include <sys/types.h>
  44. #include <sys/stat.h>
  45. #include <unistd.h>
  46. #include <fcntl.h>
  47. #include <errno.h>
  48. #include <ctype.h>
  49. #include <ipmitool/helper.h>
  50. #include <ipmitool/log.h>
  51. #include <ipmitool/ipmi.h>
  52. #include <ipmitool/ipmi_intf.h>
  53. #include <ipmitool/ipmi_session.h>
  54. // #include <ipmitool/ipmi_sdr.h>
  55. // #include <ipmitool/ipmi_sel.h>
  56. // #include <ipmitool/ipmi_fru.h>
  57. // #include <ipmitool/ipmi_lanp.h>
  58. // #include <ipmitool/ipmi_chassis.h>
  59. // #include <ipmitool/ipmi_mc.h>
  60. // #include <ipmitool/ipmi_sensor.h>
  61. // #include <ipmitool/ipmi_channel.h>
  62. // #include <ipmitool/ipmi_event.h>
  63. // #include <ipmitool/ipmi_user.h>
  64. // #include <ipmitool/ipmi_raw.h>
  65. // #include <ipmitool/ipmi_pef.h>
  66. #include <ipmitool/ipmi_oem.h>
  67. //#include <ipmitool/ipmi_ekanalyzer.h>
  68. //#include <ipmitool/ipmi_picmg.h>
  69. //#include <ipmitool/ipmi_kontronoem.h>
  70. //#include <ipmitool/ipmi_vita.h>
  71. //#include <ipmitool/ipmi_gendev.h>
  72. //#include <ipmitool/ipmi_firewall.h>
  73. //#include <ipmitool/ipmi_sol.h>
  74. //#include <ipmitool/ipmi_isol.h>
  75. #ifdef HAVE_CONFIG_H
  76. # include <config.h>
  77. #endif
  78. #ifdef ENABLE_ALL_OPTIONS
  79. # define OPTION_STRING "I:46hVvcgsEKYao:H:d:P:f:U:p:C:L:A:t:T:m:z:S:l:b:B:e:k:y:O:R:N:D:"
  80. #else
  81. # define OPTION_STRING "I:46hVvcH:f:U:p:d:S:D:"
  82. #endif
  83. /* From src/plugins/ipmi_intf.c: */
  84. void
  85. ipmi_intf_set_max_request_data_size(struct ipmi_intf * intf, uint16_t size);
  86. extern int verbose;
  87. extern int csv_output;
  88. extern const struct valstr ipmi_privlvl_vals[];
  89. extern const struct valstr ipmi_authtype_session_vals[];
  90. static struct ipmi_intf * ipmi_main_intf = NULL;
  91. // /* ipmi_password_file_read - Open file and read password from it
  92. // *
  93. // * @filename: file name to read from
  94. // *
  95. // * returns pointer to allocated buffer containing password
  96. // * (caller is expected to free when finished)
  97. // * returns NULL on error
  98. // */
  99. // static char *
  100. // ipmi_password_file_read(char * filename)
  101. // {
  102. // FILE * fp;
  103. // char * pass = NULL;
  104. // int l;
  105. // pass = malloc(21);
  106. // if (pass == NULL) {
  107. // lprintf(LOG_ERR, "ipmitool: malloc failure");
  108. // return NULL;
  109. // }
  110. // memset(pass, 0, 21);
  111. // fp = ipmi_open_file_read((const char *)filename);
  112. // if (fp == NULL) {
  113. // lprintf(LOG_ERR, "Unable to open password file %s",
  114. // filename);
  115. // free(pass);
  116. // return NULL;
  117. // }
  118. // /* read in id */
  119. // if (fgets(pass, 21, fp) == NULL) {
  120. // lprintf(LOG_ERR, "Unable to read password from file %s",
  121. // filename);
  122. // free(pass);
  123. // fclose(fp);
  124. // return NULL;
  125. // }
  126. // /* remove traling <cr><nl><tab> */
  127. // l = strcspn(pass, "\r\n\t");
  128. // if (l > 0) {
  129. // pass[l] = '\0';
  130. // }
  131. // fclose(fp);
  132. // return pass;
  133. // }
  134. /*
  135. * Print all the commands in the above table to stderr
  136. * used for help text on command line and shell
  137. */
  138. void
  139. ipmi_cmd_print(struct ipmi_cmd * cmdlist)
  140. {
  141. struct ipmi_cmd * cmd;
  142. int hdr = 0;
  143. if (cmdlist == NULL)
  144. return;
  145. for (cmd=cmdlist; cmd->func != NULL; cmd++) {
  146. if (cmd->desc == NULL)
  147. continue;
  148. if (hdr == 0) {
  149. printf( "Commands:");
  150. hdr = 1;
  151. }
  152. printf( "\t%-12s %s", cmd->name, cmd->desc);
  153. }
  154. printf( "");
  155. }
  156. /* ipmi_cmd_run - run a command from list based on parameters
  157. * called from main()
  158. *
  159. * 1. iterate through ipmi_cmd_list matching on name
  160. * 2. call func() for that command
  161. *
  162. * @intf: ipmi interface
  163. * @name: command name
  164. * @argc: command argument count
  165. * @argv: command argument list
  166. *
  167. * returns value from func() of that commnad if found
  168. * returns -1 if command is not found
  169. */
  170. int
  171. ipmi_cmd_run(struct ipmi_intf * intf, char * name, int argc, char ** argv)
  172. {
  173. struct ipmi_cmd * cmd = intf->cmdlist;
  174. /* hook to run a default command if nothing specified */
  175. if (name == NULL) {
  176. if (cmd->func == NULL || cmd->name == NULL)
  177. return -1;
  178. else if (strncmp(cmd->name, "default", 7) == 0)
  179. return cmd->func(intf, 0, NULL);
  180. else {
  181. printf("No command provided!");
  182. ipmi_cmd_print(intf->cmdlist);
  183. return -1;
  184. }
  185. }
  186. for (cmd=intf->cmdlist; cmd->func != NULL; cmd++) {
  187. if (strncmp(name, cmd->name, __maxlen(cmd->name, name)) == 0)
  188. break;
  189. }
  190. if (cmd->func == NULL) {
  191. cmd = intf->cmdlist;
  192. if (strncmp(cmd->name, "default", 7) == 0)
  193. return cmd->func(intf, argc+1, argv-1);
  194. printf("Invalid command: %s", name);
  195. ipmi_cmd_print(intf->cmdlist);
  196. return -1;
  197. }
  198. return cmd->func(intf, argc, argv);
  199. }
  200. static void
  201. ipmi_option_usage(const char * progname, struct ipmi_cmd * cmdlist, struct ipmi_intf_support * intflist)
  202. {
  203. printf("%s version %s\n", progname, VERSION);
  204. printf( "usage: %s [options...] <command>\n", progname);
  205. printf( " -h This help\n");
  206. printf( " -V Show version information\n");
  207. printf( " -v Verbose (can use multiple times)\n");
  208. printf( " -c Display output in comma separated format\n");
  209. printf( " -d N Specify a /dev/ipmiN device to use (default=0)\n");
  210. printf( " -I intf Interface to use\n");
  211. printf( " -H hostname Remote host name for LAN interface\n");
  212. printf( " -p port Remote RMCP port [default=623]\n");
  213. printf( " -U username Remote session username\n");
  214. printf( " -f file Read remote session password from file\n");
  215. printf( " -z size Change Size of Communication Channel (OEM)\n");
  216. printf( " -S sdr Use local file for remote SDR cache\n");
  217. printf( " -D tty:b[:s] Specify the serial device, baud rate to use\n");
  218. printf( " and, optionally, specify that interface is the system one\n");
  219. printf( " -4 Use only IPv4\n");
  220. printf( " -6 Use only IPv6\n");
  221. #ifdef ENABLE_ALL_OPTIONS
  222. printf( " -a Prompt for remote password\n");
  223. printf( " -Y Prompt for the Kg key for IPMIv2 authentication\n");
  224. printf( " -e char Set SOL escape character\n");
  225. printf( " -C ciphersuite Cipher suite to be used by lanplus interface\n");
  226. printf( " -k key Use Kg key for IPMIv2 authentication\n");
  227. printf( " -y hex_key Use hexadecimal-encoded Kg key for IPMIv2 authentication\n");
  228. printf( " -L level Remote session privilege level [default=ADMINISTRATOR]\n");
  229. printf( " Append a '+' to use name/privilege lookup in RAKP1\n");
  230. printf( " -A authtype Force use of auth type NONE, PASSWORD, MD2, MD5 or OEM\n");
  231. printf( " -P password Remote session password\n");
  232. printf( " -E Read password from IPMI_PASSWORD environment variable\n");
  233. printf( " -K Read kgkey from IPMI_KGKEY environment variable\n");
  234. printf( " -m address Set local IPMB address\n");
  235. printf( " -b channel Set destination channel for bridged request\n");
  236. printf( " -t address Bridge request to remote target address\n");
  237. printf( " -B channel Set transit channel for bridged request (dual bridge)\n");
  238. printf( " -T address Set transit address for bridge request (dual bridge)\n");
  239. printf( " -l lun Set destination lun for raw commands\n");
  240. printf( " -o oemtype Setup for OEM (use 'list' to see available OEM types)\n");
  241. printf( " -O seloem Use file for OEM SEL event descriptions\n");
  242. printf( " -N seconds Specify timeout for lan [default=2] / lanplus [default=1] interface\n");
  243. printf( " -R retry Set the number of retries for lan/lanplus interface [default=4]\n");
  244. #endif
  245. printf( "\n");
  246. ipmi_intf_print(intflist);
  247. if (cmdlist != NULL)
  248. ipmi_cmd_print(cmdlist);
  249. }
  250. /* ipmi_catch_sigint - Handle the interrupt signal (Ctrl-C), close the
  251. * interface, and exit ipmitool with error (-1)
  252. *
  253. * This insures that the IOL session gets freed
  254. * for other callers.
  255. *
  256. * returns -1
  257. */
  258. void ipmi_catch_sigint()
  259. {
  260. if (ipmi_main_intf != NULL) {
  261. printf("\nSIGN INT: Close Interface %s\n",ipmi_main_intf->desc);
  262. /* reduce retry count to a single retry */
  263. ipmi_main_intf->ssn_params.retry = 1;
  264. /* close interface */
  265. ipmi_main_intf->close(ipmi_main_intf);
  266. }
  267. exit(-1);
  268. }
  269. // static uint8_t
  270. // ipmi_acquire_ipmb_address(struct ipmi_intf * intf)
  271. // {
  272. // if (intf->picmg_avail) {
  273. // return ipmi_picmg_ipmb_address(intf);
  274. // } else if (intf->vita_avail) {
  275. // return ipmi_vita_ipmb_address(intf);
  276. // } else {
  277. // return 0;
  278. // }
  279. // }
  280. /* ipmi_parse_options - helper function to handle parsing command line options
  281. *
  282. * @argc: count of options
  283. * @argv: list of options
  284. * @cmdlist: list of supported commands
  285. * @intflist: list of supported interfaces
  286. *
  287. * returns 0 on success
  288. * returns -1 on error
  289. */
  290. int
  291. ipmi_main(int argc, char ** argv,
  292. struct ipmi_cmd * cmdlist,
  293. struct ipmi_intf_support * intflist)
  294. {
  295. struct ipmi_intf_support * sup;
  296. int privlvl = 0;
  297. uint8_t target_addr = 0;
  298. uint8_t target_channel = 0;
  299. uint8_t transit_addr = 0;
  300. uint8_t transit_channel = 0;
  301. uint8_t target_lun = 0;
  302. uint8_t arg_addr = 0;
  303. uint8_t addr = 0;
  304. uint16_t my_long_packet_size=0;
  305. uint8_t my_long_packet_set=0;
  306. uint8_t lookupbit = 0x10; /* use name-only lookup by default */
  307. int retry = 0;
  308. uint32_t timeout = 0;
  309. int authtype = -1;
  310. char * tmp_pass = NULL;
  311. char * tmp_env = NULL;
  312. char * hostname = NULL;
  313. char * username = NULL;
  314. char * password = NULL;
  315. char * intfname = NULL;
  316. char * progname = NULL;
  317. char * oemtype = NULL;
  318. char * sdrcache = NULL;
  319. uint8_t kgkey[IPMI_KG_BUFFER_SIZE];
  320. char * seloem = NULL;
  321. int port = 0;
  322. int devnum = 0;
  323. int cipher_suite_id = 3; /* See table 22-19 of the IPMIv2 spec */
  324. int argflag, i, found;
  325. int rc = -1;
  326. int ai_family = AF_UNSPEC;
  327. // char sol_escape_char = SOL_ESCAPE_CHARACTER_DEFAULT;
  328. char * devfile = NULL;
  329. /* save program name */
  330. progname = strrchr(argv[0], '/');
  331. progname = ((progname == NULL) ? argv[0] : progname+1);
  332. signal(SIGINT, ipmi_catch_sigint);
  333. memset(kgkey, 0, sizeof(kgkey));
  334. while ((argflag = getopt(argc, (char **)argv, OPTION_STRING)) != -1)
  335. {
  336. switch (argflag) {
  337. case 'I':
  338. if (intfname) {
  339. free(intfname);
  340. intfname = NULL;
  341. }
  342. intfname = strdup(optarg);
  343. if (intfname == NULL) {
  344. printf( "%s: malloc failure", progname);
  345. goto out_free;
  346. }
  347. if (intflist != NULL) {
  348. found = 0;
  349. for (sup=intflist; sup->name != NULL; sup++) {
  350. if (strncmp(sup->name, intfname, strlen(intfname)) == 0 &&
  351. strncmp(sup->name, intfname, strlen(sup->name)) == 0 &&
  352. sup->supported == 1)
  353. found = 1;
  354. }
  355. if (!found) {
  356. printf( "Interface %s not supported", intfname);
  357. goto out_free;
  358. }
  359. }
  360. break;
  361. case 'h':
  362. ipmi_option_usage(progname, cmdlist, intflist);
  363. rc = 0;
  364. goto out_free;
  365. break;
  366. case 'V':
  367. printf("%s version %s\n", progname, VERSION);
  368. rc = 0;
  369. goto out_free;
  370. break;
  371. // case 'd':
  372. // if (str2int(optarg, &devnum) != 0) {
  373. // lprintf(LOG_ERR, "Invalid parameter given or out of range for '-d'.");
  374. // rc = -1;
  375. // goto out_free;
  376. // }
  377. // /* Check if device number is -gt 0; I couldn't find limit for
  378. // * kernels > 2.6, thus right side is unlimited.
  379. // */
  380. // if (devnum < 0) {
  381. // lprintf(LOG_ERR, "Device number %i is out of range.", devnum);
  382. // rc = -1;
  383. // goto out_free;
  384. // }
  385. // break;
  386. // case 'p':
  387. // if (str2int(optarg, &port) != 0) {
  388. // lprintf(LOG_ERR, "Invalid parameter given or out of range for '-p'.");
  389. // rc = -1;
  390. // goto out_free;
  391. // }
  392. // /* Check if port is -gt 0 && port is -lt 65535 */
  393. // if (port < 0 || port > 65535) {
  394. // lprintf(LOG_ERR, "Port number %i is out of range.", port);
  395. // rc = -1;
  396. // goto out_free;
  397. // }
  398. // break;
  399. // case 'C':
  400. // if (str2int(optarg, &cipher_suite_id) != 0) {
  401. // lprintf(LOG_ERR, "Invalid parameter given or out of range for '-C'.");
  402. // rc = -1;
  403. // goto out_free;
  404. // }
  405. // /* add check Cipher is -gt 0 */
  406. // if (cipher_suite_id < 0) {
  407. // lprintf(LOG_ERR, "Cipher suite ID %i is invalid.", cipher_suite_id);
  408. // rc = -1;
  409. // goto out_free;
  410. // }
  411. // break;
  412. // case 'v':
  413. // verbose++;
  414. // break;
  415. // case 'c':
  416. // csv_output = 1;
  417. // break;
  418. case 'H':
  419. if (hostname) {
  420. free(hostname);
  421. hostname = NULL;
  422. }
  423. hostname = strdup(optarg);
  424. if (hostname == NULL) {
  425. printf( "%s: malloc failure", progname);
  426. goto out_free;
  427. }
  428. break;
  429. // case 'f':
  430. // if (password) {
  431. // free(password);
  432. // password = NULL;
  433. // }
  434. // password = ipmi_password_file_read(optarg);
  435. // if (password == NULL)
  436. // lprintf(LOG_ERR, "Unable to read password "
  437. // "from file %s", optarg);
  438. // break;
  439. // case 'a':
  440. // #ifdef HAVE_GETPASSPHRASE
  441. // tmp_pass = getpassphrase("Password: ");
  442. // #else
  443. // tmp_pass = getpass("Password: ");
  444. // #endif
  445. // if (tmp_pass != NULL) {
  446. // if (password) {
  447. // free(password);
  448. // password = NULL;
  449. // }
  450. // password = strdup(tmp_pass);
  451. // tmp_pass = NULL;
  452. // if (password == NULL) {
  453. // lprintf(LOG_ERR, "%s: malloc failure", progname);
  454. // goto out_free;
  455. // }
  456. // }
  457. // break;
  458. // case 'k':
  459. // memset(kgkey, 0, sizeof(kgkey));
  460. // strncpy((char *)kgkey, optarg, sizeof(kgkey) - 1);
  461. // break;
  462. // case 'K':
  463. // if ((tmp_env = getenv("IPMI_KGKEY"))) {
  464. // memset(kgkey, 0, sizeof(kgkey));
  465. // strncpy((char *)kgkey, tmp_env,
  466. // sizeof(kgkey) - 1);
  467. // } else {
  468. // lprintf(LOG_WARN, "Unable to read kgkey from environment");
  469. // }
  470. // break;
  471. // case 'y':
  472. // memset(kgkey, 0, sizeof(kgkey));
  473. // rc = ipmi_parse_hex(optarg, kgkey, sizeof(kgkey) - 1);
  474. // if (rc == -1) {
  475. // lprintf(LOG_ERR, "Number of Kg key characters is not even");
  476. // goto out_free;
  477. // } else if (rc == -3) {
  478. // lprintf(LOG_ERR, "Kg key is not hexadecimal number");
  479. // goto out_free;
  480. // } else if (rc > (IPMI_KG_BUFFER_SIZE-1)) {
  481. // lprintf(LOG_ERR, "Kg key is too long");
  482. // goto out_free;
  483. // }
  484. // break;
  485. // case 'Y':
  486. // #ifdef HAVE_GETPASSPHRASE
  487. // tmp_pass = getpassphrase("Key: ");
  488. // #else
  489. // tmp_pass = getpass("Key: ");
  490. // #endif
  491. // if (tmp_pass != NULL) {
  492. // memset(kgkey, 0, sizeof(kgkey));
  493. // strncpy((char *)kgkey, tmp_pass,
  494. // sizeof(kgkey) - 1);
  495. // tmp_pass = NULL;
  496. // }
  497. // break;
  498. case 'U':
  499. if (username) {
  500. free(username);
  501. username = NULL;
  502. }
  503. if (strlen(optarg) > 16) {
  504. printf( "Username is too long (> 16 bytes)");
  505. goto out_free;
  506. }
  507. username = strdup(optarg);
  508. if (username == NULL) {
  509. printf( "%s: malloc failure", progname);
  510. goto out_free;
  511. }
  512. break;
  513. // case 'S':
  514. // if (sdrcache) {
  515. // free(sdrcache);
  516. // sdrcache = NULL;
  517. // }
  518. // sdrcache = strdup(optarg);
  519. // if (sdrcache == NULL) {
  520. // lprintf(LOG_ERR, "%s: malloc failure", progname);
  521. // goto out_free;
  522. // }
  523. // break;
  524. // case 'D':
  525. // /* check for subsequent instance of -D */
  526. // if (devfile) {
  527. // /* free memory for previous string */
  528. // free(devfile);
  529. // }
  530. // devfile = strdup(optarg);
  531. // if (devfile == NULL) {
  532. // lprintf(LOG_ERR, "%s: malloc failure", progname);
  533. // goto out_free;
  534. // }
  535. // break;
  536. // case '4':
  537. // /* IPv4 only */
  538. // if (ai_family == AF_UNSPEC) {
  539. // ai_family = AF_INET;
  540. // } else {
  541. // if (ai_family == AF_INET6) {
  542. // lprintf(LOG_ERR,
  543. // "Parameter is mutually exclusive with -6.");
  544. // } else {
  545. // lprintf(LOG_ERR,
  546. // "Multiple -4 parameters given.");
  547. // }
  548. // rc = (-1);
  549. // goto out_free;
  550. // }
  551. // break;
  552. // case '6':
  553. // /* IPv6 only */
  554. // if (ai_family == AF_UNSPEC) {
  555. // ai_family = AF_INET6;
  556. // } else {
  557. // if (ai_family == AF_INET) {
  558. // lprintf(LOG_ERR,
  559. // "Parameter is mutually exclusive with -4.");
  560. // } else {
  561. // lprintf(LOG_ERR,
  562. // "Multiple -6 parameters given.");
  563. // }
  564. // rc = (-1);
  565. // goto out_free;
  566. // }
  567. // break;
  568. #ifdef ENABLE_ALL_OPTIONS
  569. // case 'o':
  570. // if (oemtype) {
  571. // free(oemtype);
  572. // oemtype = NULL;
  573. // }
  574. // oemtype = strdup(optarg);
  575. // if (oemtype == NULL) {
  576. // lprintf(LOG_ERR, "%s: malloc failure", progname);
  577. // goto out_free;
  578. // }
  579. // if (strncmp(oemtype, "list", 4) == 0 ||
  580. // strncmp(oemtype, "help", 4) == 0) {
  581. // ipmi_oem_print();
  582. // rc = 0;
  583. // goto out_free;
  584. // }
  585. // break;
  586. // case 'g':
  587. // /* backwards compatible oem hack */
  588. // if (oemtype) {
  589. // free(oemtype);
  590. // oemtype = NULL;
  591. // }
  592. // oemtype = strdup("intelwv2");
  593. // break;
  594. // case 's':
  595. // /* backwards compatible oem hack */
  596. // if (oemtype) {
  597. // free(oemtype);
  598. // oemtype = NULL;
  599. // }
  600. // oemtype = strdup("supermicro");
  601. // break;
  602. case 'P':
  603. if (password) {
  604. free(password);
  605. password = NULL;
  606. }
  607. password = strdup(optarg);
  608. if (password == NULL) {
  609. printf( "%s: malloc failure", progname);
  610. goto out_free;
  611. }
  612. /* Prevent password snooping with ps */
  613. i = strlen(optarg);
  614. memset(optarg, 'X', i);
  615. printf("---> get P: %s\n", password);
  616. break;
  617. // case 'E':
  618. // if ((tmp_env = getenv("IPMITOOL_PASSWORD"))) {
  619. // if (password) {
  620. // free(password);
  621. // password = NULL;
  622. // }
  623. // password = strdup(tmp_env);
  624. // if (password == NULL) {
  625. // lprintf(LOG_ERR, "%s: malloc failure", progname);
  626. // goto out_free;
  627. // }
  628. // }
  629. // else if ((tmp_env = getenv("IPMI_PASSWORD"))) {
  630. // if (password) {
  631. // free(password);
  632. // password = NULL;
  633. // }
  634. // password = strdup(tmp_env);
  635. // if (password == NULL) {
  636. // lprintf(LOG_ERR, "%s: malloc failure", progname);
  637. // goto out_free;
  638. // }
  639. // }
  640. // else {
  641. // lprintf(LOG_WARN, "Unable to read password from environment");
  642. // }
  643. // break;
  644. // case 'L':
  645. // i = strlen(optarg);
  646. // if ((i > 0) && (optarg[i-1] == '+')) {
  647. // lookupbit = 0;
  648. // optarg[i-1] = 0;
  649. // }
  650. // privlvl = str2val(optarg, ipmi_privlvl_vals);
  651. // if (privlvl == 0xFF) {
  652. // lprintf(LOG_WARN, "Invalid privilege level %s", optarg);
  653. // }
  654. // break;
  655. // case 'A':
  656. // authtype = str2val(optarg, ipmi_authtype_session_vals);
  657. // break;
  658. case 't':
  659. if (str2uchar(optarg, &target_addr) != 0) {
  660. printf( "Invalid parameter given or out of range for '-t'.");
  661. rc = -1;
  662. goto out_free;
  663. }
  664. break;
  665. case 'b':
  666. if (str2uchar(optarg, &target_channel) != 0) {
  667. printf( "Invalid parameter given or out of range for '-b'.");
  668. rc = -1;
  669. goto out_free;
  670. }
  671. break;
  672. // case 'T':
  673. // if (str2uchar(optarg, &transit_addr) != 0) {
  674. // lprintf(LOG_ERR, "Invalid parameter given or out of range for '-T'.");
  675. // rc = -1;
  676. // goto out_free;
  677. // }
  678. // break;
  679. // case 'B':
  680. // if (str2uchar(optarg, &transit_channel) != 0) {
  681. // lprintf(LOG_ERR, "Invalid parameter given or out of range for '-B'.");
  682. // rc = -1;
  683. // goto out_free;
  684. // }
  685. // break;
  686. // case 'l':
  687. // if (str2uchar(optarg, &target_lun) != 0) {
  688. // lprintf(LOG_ERR, "Invalid parameter given or out of range for '-l'.");
  689. // rc = 1;
  690. // goto out_free;
  691. // }
  692. // break;
  693. case 'm':
  694. if (str2uchar(optarg, &arg_addr) != 0) {
  695. printf( "Invalid parameter given or out of range for '-m'.");
  696. rc = -1;
  697. goto out_free;
  698. }
  699. break;
  700. // case 'e':
  701. // sol_escape_char = optarg[0];
  702. // break;
  703. // case 'O':
  704. // if (seloem) {
  705. // free(seloem);
  706. // seloem = NULL;
  707. // }
  708. // seloem = strdup(optarg);
  709. // if (seloem == NULL) {
  710. // lprintf(LOG_ERR, "%s: malloc failure", progname);
  711. // goto out_free;
  712. // }
  713. // break;
  714. // case 'z':
  715. // if (str2ushort(optarg, &my_long_packet_size) != 0) {
  716. // lprintf(LOG_ERR, "Invalid parameter given or out of range for '-z'.");
  717. // rc = -1;
  718. // goto out_free;
  719. // }
  720. // break;
  721. // /* Retry and Timeout */
  722. // case 'R':
  723. // if (str2int(optarg, &retry) != 0 || retry < 0) {
  724. // lprintf(LOG_ERR, "Invalid parameter given or out of range for '-R'.");
  725. // rc = -1;
  726. // goto out_free;
  727. // }
  728. // break;
  729. // case 'N':
  730. // if (str2uint(optarg, &timeout) != 0) {
  731. // lprintf(LOG_ERR, "Invalid parameter given or out of range for '-N'.");
  732. // rc = -1;
  733. // goto out_free;
  734. // }
  735. // break;
  736. #endif
  737. default:
  738. ipmi_option_usage(progname, cmdlist, intflist);
  739. goto out_free;
  740. }
  741. }
  742. /* check for command before doing anything */
  743. if (argc-optind > 0 &&
  744. strncmp(argv[optind], "help", 4) == 0) {
  745. ipmi_cmd_print(cmdlist);
  746. rc = 0;
  747. goto out_free;
  748. }
  749. // /*
  750. // * If the user has specified a hostname (-H option)
  751. // * then this is a remote access session.
  752. // *
  753. // * If no password was specified by any other method
  754. // * and the authtype was not explicitly set to NONE
  755. // * then prompt the user.
  756. // */
  757. // if (hostname != NULL && password == NULL &&
  758. // (authtype != IPMI_SESSION_AUTHTYPE_NONE || authtype < 0)) {
  759. // #ifdef HAVE_GETPASSPHRASE
  760. // tmp_pass = getpassphrase("Password: ");
  761. // #else
  762. // tmp_pass = getpass("Password: ");
  763. // #endif
  764. // if (tmp_pass != NULL) {
  765. // password = strdup(tmp_pass);
  766. // tmp_pass = NULL;
  767. // if (password == NULL) {
  768. // lprintf(LOG_ERR, "%s: malloc failure", progname);
  769. // goto out_free;
  770. // }
  771. // }
  772. // }
  773. //jimbo
  774. if (password == NULL) {
  775. printf("No password!\n");
  776. goto out_free;
  777. }
  778. /* if no interface was specified but a
  779. * hostname was then use LAN by default
  780. * otherwise the default is hardcoded
  781. * to use the first entry in the list
  782. */
  783. if (intfname == NULL && hostname != NULL) {
  784. intfname = strdup("lan");
  785. if (intfname == NULL) {
  786. printf( "%s: malloc failure", progname);
  787. goto out_free;
  788. }
  789. }
  790. if (password != NULL && intfname != NULL) {
  791. if (strcmp(intfname, "lan") == 0 && strlen(password) > 16) {
  792. printf( "%s: password is longer than 16 bytes.", intfname);
  793. rc = -1;
  794. goto out_free;
  795. } else if (strcmp(intfname, "lanplus") == 0 && strlen(password) > 20) {
  796. printf( "%s: password is longer than 20 bytes.", intfname);
  797. rc = -1;
  798. goto out_free;
  799. }
  800. } /* if (password != NULL && intfname != NULL) */
  801. /* load interface */
  802. printf("---> intfname: %s, hostname: %s, username: %s, password: %s\n", intfname, hostname, username, password);
  803. ipmi_main_intf = ipmi_intf_load(intfname);
  804. if (ipmi_main_intf == NULL) {
  805. printf( "Error loading interface %s", intfname);
  806. goto out_free;
  807. }
  808. // /* setup log */
  809. // log_init(progname, 0, verbose);
  810. // /* run OEM setup if found */
  811. // if (oemtype != NULL &&
  812. // ipmi_oem_setup(ipmi_main_intf, oemtype) < 0) {
  813. // lprintf(LOG_ERR, "OEM setup for \"%s\" failed", oemtype);
  814. // goto out_free;
  815. // }
  816. /* set session variables */
  817. if (hostname != NULL)
  818. ipmi_intf_session_set_hostname(ipmi_main_intf, hostname);
  819. if (username != NULL)
  820. ipmi_intf_session_set_username(ipmi_main_intf, username);
  821. if (password != NULL)
  822. ipmi_intf_session_set_password(ipmi_main_intf, password);
  823. ipmi_intf_session_set_kgkey(ipmi_main_intf, kgkey);
  824. if (port > 0)
  825. ipmi_intf_session_set_port(ipmi_main_intf, port);
  826. if (authtype >= 0)
  827. ipmi_intf_session_set_authtype(ipmi_main_intf, (uint8_t)authtype);
  828. if (privlvl > 0)
  829. ipmi_intf_session_set_privlvl(ipmi_main_intf, (uint8_t)privlvl);
  830. else
  831. ipmi_intf_session_set_privlvl(ipmi_main_intf,
  832. IPMI_SESSION_PRIV_ADMIN); /* default */
  833. /* Adding retry and timeout for interface that support it */
  834. if (retry > 0)
  835. ipmi_intf_session_set_retry(ipmi_main_intf, retry);
  836. if (timeout > 0)
  837. ipmi_intf_session_set_timeout(ipmi_main_intf, timeout);
  838. ipmi_intf_session_set_lookupbit(ipmi_main_intf, lookupbit);
  839. // ipmi_intf_session_set_sol_escape_char(ipmi_main_intf, sol_escape_char);
  840. ipmi_intf_session_set_cipher_suite_id(ipmi_main_intf, cipher_suite_id);
  841. printf("---> port: %d, authtype: %d, privlvl: %d, retry: %d\n", port, authtype, privlvl, retry);
  842. ipmi_main_intf->devnum = devnum;
  843. /* setup device file if given */
  844. ipmi_main_intf->devfile = devfile;
  845. ipmi_main_intf->ai_family = ai_family;
  846. /* Open the interface with the specified or default IPMB address */
  847. ipmi_main_intf->my_addr = arg_addr ? arg_addr : IPMI_BMC_SLAVE_ADDR;
  848. if (ipmi_main_intf->open != NULL) {
  849. if (ipmi_main_intf->open(ipmi_main_intf) < 0) {
  850. goto out_free;
  851. }
  852. }
  853. // if (!ipmi_oem_active(ipmi_main_intf, "i82571spt")) {
  854. // /*
  855. // * Attempt picmg/vita discovery of the actual interface
  856. // * address, unless the users specified an address.
  857. // * Address specification always overrides discovery
  858. // */
  859. // if (picmg_discover(ipmi_main_intf)) {
  860. // ipmi_main_intf->picmg_avail = 1;
  861. // } else if (vita_discover(ipmi_main_intf)) {
  862. // ipmi_main_intf->vita_avail = 1;
  863. // }
  864. // }
  865. if (arg_addr) {
  866. addr = arg_addr;
  867. }
  868. // else if (!ipmi_oem_active(ipmi_main_intf, "i82571spt")) {
  869. // lprintf(LOG_DEBUG, "Acquire IPMB address");
  870. // addr = ipmi_acquire_ipmb_address(ipmi_main_intf);
  871. // lprintf(LOG_INFO, "Discovered IPMB address 0x%x", addr);
  872. // }
  873. /*
  874. * If we discovered the ipmb address and it is not the same as what we
  875. * used for open, Set the discovered IPMB address as my address if the
  876. * interface supports it.
  877. */
  878. if (addr != 0 && addr != ipmi_main_intf->my_addr) {
  879. if (ipmi_main_intf->set_my_addr) {
  880. /*
  881. * Some interfaces need special handling
  882. * when changing local address
  883. */
  884. (void)ipmi_main_intf->set_my_addr(ipmi_main_intf, addr);
  885. }
  886. /* set local address */
  887. ipmi_main_intf->my_addr = addr;
  888. }
  889. ipmi_main_intf->target_addr = ipmi_main_intf->my_addr;
  890. /* If bridging addresses are specified, handle them */
  891. if (transit_addr > 0 || target_addr > 0) {
  892. /* sanity check, transit makes no sense without a target */
  893. if ((transit_addr != 0 || transit_channel != 0) &&
  894. target_addr == 0) {
  895. printf("Transit address/channel %#x/%#x ignored. "
  896. "Target address must be specified!",
  897. transit_addr, transit_channel);
  898. goto out_free;
  899. }
  900. ipmi_main_intf->target_addr = target_addr;
  901. ipmi_main_intf->target_channel = target_channel ;
  902. ipmi_main_intf->transit_addr = transit_addr;
  903. ipmi_main_intf->transit_channel = transit_channel;
  904. /* must be admin level to do this over lan */
  905. ipmi_intf_session_set_privlvl(ipmi_main_intf, IPMI_SESSION_PRIV_ADMIN);
  906. // /* Get the ipmb address of the targeted entity */
  907. // ipmi_main_intf->target_ipmb_addr =
  908. // ipmi_acquire_ipmb_address(ipmi_main_intf);
  909. printf("Specified addressing Target %#x:%#x Transit %#x:%#x",
  910. ipmi_main_intf->target_addr,
  911. ipmi_main_intf->target_channel,
  912. ipmi_main_intf->transit_addr,
  913. ipmi_main_intf->transit_channel);
  914. if (ipmi_main_intf->target_ipmb_addr) {
  915. printf("Discovered Target IPMB-0 address %#x",
  916. ipmi_main_intf->target_ipmb_addr);
  917. }
  918. }
  919. /* set target LUN (for RAW command) */
  920. ipmi_main_intf->target_lun = target_lun ;
  921. printf("Interface address: my_addr %#x "
  922. "transit %#x:%#x target %#x:%#x "
  923. "ipmb_target %#x\n",
  924. ipmi_main_intf->my_addr,
  925. ipmi_main_intf->transit_addr,
  926. ipmi_main_intf->transit_channel,
  927. ipmi_main_intf->target_addr,
  928. ipmi_main_intf->target_channel,
  929. ipmi_main_intf->target_ipmb_addr);
  930. // /* parse local SDR cache if given */
  931. // if (sdrcache != NULL) {
  932. // ipmi_sdr_list_cache_fromfile(ipmi_main_intf, sdrcache);
  933. // }
  934. // /* Parse SEL OEM file if given */
  935. // if (seloem != NULL) {
  936. // ipmi_sel_oem_init(seloem);
  937. // }
  938. // /* Enable Big Buffer when requested */
  939. // if ( my_long_packet_size != 0 ) {
  940. // /* Enable Big Buffer when requested */
  941. // if (!ipmi_oem_active(ipmi_main_intf, "kontron") ||
  942. // ipmi_kontronoem_set_large_buffer(ipmi_main_intf,
  943. // my_long_packet_size ) == 0) {
  944. // printf("Setting large buffer to %i\n", my_long_packet_size);
  945. // my_long_packet_set = 1;
  946. // ipmi_intf_set_max_request_data_size(ipmi_main_intf,
  947. // my_long_packet_size);
  948. // }
  949. // }
  950. ipmi_main_intf->cmdlist = cmdlist;
  951. /* now we finally run the command */
  952. if (argc-optind > 0)
  953. rc = ipmi_cmd_run(ipmi_main_intf, argv[optind], argc-optind-1,
  954. &(argv[optind+1]));
  955. else
  956. rc = ipmi_cmd_run(ipmi_main_intf, NULL, 0, NULL);
  957. // if (my_long_packet_set == 1) {
  958. // if (ipmi_oem_active(ipmi_main_intf, "kontron")) {
  959. // /* Restore defaults */
  960. // ipmi_kontronoem_set_large_buffer( ipmi_main_intf, 0 );
  961. // }
  962. // }
  963. /* clean repository caches */
  964. ipmi_cleanup(ipmi_main_intf);
  965. /* call interface close function if available */
  966. if (ipmi_main_intf->opened > 0 && ipmi_main_intf->close != NULL)
  967. ipmi_main_intf->close(ipmi_main_intf);
  968. out_free:
  969. //log_halt();
  970. if (intfname != NULL) {
  971. free(intfname);
  972. intfname = NULL;
  973. }
  974. if (hostname != NULL) {
  975. free(hostname);
  976. hostname = NULL;
  977. }
  978. if (username != NULL) {
  979. free(username);
  980. username = NULL;
  981. }
  982. if (password != NULL) {
  983. free(password);
  984. password = NULL;
  985. }
  986. if (oemtype != NULL) {
  987. free(oemtype);
  988. oemtype = NULL;
  989. }
  990. if (seloem != NULL) {
  991. free(seloem);
  992. seloem = NULL;
  993. }
  994. if (sdrcache != NULL) {
  995. free(sdrcache);
  996. sdrcache = NULL;
  997. }
  998. if (devfile) {
  999. free(devfile);
  1000. devfile = NULL;
  1001. }
  1002. return rc;
  1003. }