ipmi_main.c 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071
  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. lprintf(LOG_NOTICE, "Commands:");
  152. hdr = 1;
  153. }
  154. lprintf(LOG_NOTICE, "\t%-12s %s", cmd->name, cmd->desc);
  155. }
  156. lprintf(LOG_NOTICE, "");
  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. lprintf(LOG_ERR, "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. lprintf(LOG_ERR, "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. lprintf(LOG_NOTICE, "%s version %s\n", progname, VERSION);
  206. lprintf(LOG_NOTICE, "usage: %s [options...] <command>\n", progname);
  207. lprintf(LOG_NOTICE, " -h This help");
  208. lprintf(LOG_NOTICE, " -V Show version information");
  209. lprintf(LOG_NOTICE, " -v Verbose (can use multiple times)");
  210. lprintf(LOG_NOTICE, " -c Display output in comma separated format");
  211. lprintf(LOG_NOTICE, " -d N Specify a /dev/ipmiN device to use (default=0)");
  212. lprintf(LOG_NOTICE, " -I intf Interface to use");
  213. lprintf(LOG_NOTICE, " -H hostname Remote host name for LAN interface");
  214. lprintf(LOG_NOTICE, " -p port Remote RMCP port [default=623]");
  215. lprintf(LOG_NOTICE, " -U username Remote session username");
  216. lprintf(LOG_NOTICE, " -f file Read remote session password from file");
  217. lprintf(LOG_NOTICE, " -z size Change Size of Communication Channel (OEM)");
  218. lprintf(LOG_NOTICE, " -S sdr Use local file for remote SDR cache");
  219. lprintf(LOG_NOTICE, " -D tty:b[:s] Specify the serial device, baud rate to use");
  220. lprintf(LOG_NOTICE, " and, optionally, specify that interface is the system one");
  221. lprintf(LOG_NOTICE, " -4 Use only IPv4");
  222. lprintf(LOG_NOTICE, " -6 Use only IPv6");
  223. #ifdef ENABLE_ALL_OPTIONS
  224. lprintf(LOG_NOTICE, " -a Prompt for remote password");
  225. lprintf(LOG_NOTICE, " -Y Prompt for the Kg key for IPMIv2 authentication");
  226. lprintf(LOG_NOTICE, " -e char Set SOL escape character");
  227. lprintf(LOG_NOTICE, " -C ciphersuite Cipher suite to be used by lanplus interface");
  228. lprintf(LOG_NOTICE, " -k key Use Kg key for IPMIv2 authentication");
  229. lprintf(LOG_NOTICE, " -y hex_key Use hexadecimal-encoded Kg key for IPMIv2 authentication");
  230. lprintf(LOG_NOTICE, " -L level Remote session privilege level [default=ADMINISTRATOR]");
  231. lprintf(LOG_NOTICE, " Append a '+' to use name/privilege lookup in RAKP1");
  232. lprintf(LOG_NOTICE, " -A authtype Force use of auth type NONE, PASSWORD, MD2, MD5 or OEM");
  233. lprintf(LOG_NOTICE, " -P password Remote session password");
  234. lprintf(LOG_NOTICE, " -E Read password from IPMI_PASSWORD environment variable");
  235. lprintf(LOG_NOTICE, " -K Read kgkey from IPMI_KGKEY environment variable");
  236. lprintf(LOG_NOTICE, " -m address Set local IPMB address");
  237. lprintf(LOG_NOTICE, " -b channel Set destination channel for bridged request");
  238. lprintf(LOG_NOTICE, " -t address Bridge request to remote target address");
  239. lprintf(LOG_NOTICE, " -B channel Set transit channel for bridged request (dual bridge)");
  240. lprintf(LOG_NOTICE, " -T address Set transit address for bridge request (dual bridge)");
  241. lprintf(LOG_NOTICE, " -l lun Set destination lun for raw commands");
  242. lprintf(LOG_NOTICE, " -o oemtype Setup for OEM (use 'list' to see available OEM types)");
  243. lprintf(LOG_NOTICE, " -O seloem Use file for OEM SEL event descriptions");
  244. lprintf(LOG_NOTICE, " -N seconds Specify timeout for lan [default=2] / lanplus [default=1] interface");
  245. lprintf(LOG_NOTICE, " -R retry Set the number of retries for lan/lanplus interface [default=4]");
  246. #endif
  247. lprintf(LOG_NOTICE, "");
  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. lprintf(LOG_ERR, "%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. lprintf(LOG_ERR, "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. lprintf(LOG_ERR, "%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. lprintf(LOG_ERR, "Username is too long (> 16 bytes)");
  507. goto out_free;
  508. }
  509. username = strdup(optarg);
  510. if (username == NULL) {
  511. lprintf(LOG_ERR, "%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. lprintf(LOG_ERR, "%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. lprintf(LOG_ERR, "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. lprintf(LOG_ERR, "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. lprintf(LOG_ERR, "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. lprintf(LOG_ERR, "%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. lprintf(LOG_ERR, "%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. lprintf(LOG_ERR, "%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. lprintf(LOG_ERR, "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. lprintf(LOG_ERR,
  895. "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. lprintf(LOG_DEBUG, "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. lprintf(LOG_INFO, "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. lprintf(LOG_DEBUG, "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. }