ipmi_main.c 30 KB

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