ipmi_session.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449
  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. #include <stdlib.h>
  33. #include <stdio.h>
  34. #include <string.h>
  35. #include <sys/types.h>
  36. #include <sys/socket.h>
  37. #include <netinet/in.h>
  38. #include <arpa/inet.h>
  39. #include <errno.h>
  40. #include <unistd.h>
  41. #include <signal.h>
  42. #include <ipmitool/ipmi.h>
  43. #include <ipmitool/ipmi_intf.h>
  44. #include <ipmitool/helper.h>
  45. #include <ipmitool/log.h>
  46. #include <ipmitool/ipmi_lanp.h>
  47. #include <ipmitool/ipmi_session.h>
  48. #include <ipmitool/ipmi_strings.h>
  49. #include <ipmitool/bswap.h>
  50. typedef enum {
  51. IPMI_SESSION_REQUEST_CURRENT = 0,
  52. IPMI_SESSION_REQUEST_ALL,
  53. IPMI_SESSION_REQUEST_BY_ID,
  54. IPMI_SESSION_REQUEST_BY_HANDLE
  55. } Ipmi_Session_Request_Type;
  56. /*
  57. * print_session_info_csv
  58. */
  59. static void
  60. print_session_info_csv(const struct get_session_info_rsp * session_info,
  61. int data_len)
  62. {
  63. char buffer[18];
  64. uint16_t console_port_tmp;
  65. printf("%d", session_info->session_handle);
  66. printf(",%d", session_info->session_slot_count);
  67. printf(",%d", session_info->active_session_count);
  68. if (data_len == 3)
  69. {
  70. /* There is no session data here*/
  71. printf("\n");
  72. return;
  73. }
  74. printf(",%d", session_info->user_id);
  75. printf(",%s", val2str(session_info->privilege_level, ipmi_privlvl_vals));
  76. printf(",%s", session_info->auxiliary_data?
  77. "IPMIv2/RMCP+" : "IPMIv1.5");
  78. printf(",0x%02x", session_info->channel_number);
  79. if (data_len == 18)
  80. {
  81. /* We have 802.3 LAN data */
  82. printf(",%s",
  83. inet_ntop(AF_INET,
  84. &(session_info->channel_data.lan_data.console_ip),
  85. buffer,
  86. 16));
  87. printf(",%s", mac2str(
  88. session_info->channel_data.lan_data.console_mac));
  89. console_port_tmp = session_info->channel_data.lan_data.console_port;
  90. #if WORDS_BIGENDIAN
  91. console_port_tmp = BSWAP_16(console_port_tmp);
  92. #endif
  93. printf(",%d", console_port_tmp);
  94. }
  95. else if ((data_len == 12) || (data_len == 14))
  96. {
  97. /* Channel async serial/modem */
  98. printf(",%s",
  99. val2str(session_info->channel_data.modem_data.session_channel_activity_type,
  100. ipmi_channel_activity_type_vals));
  101. printf(",%d",
  102. session_info->channel_data.modem_data.destination_selector);
  103. printf(",%s",
  104. inet_ntop(AF_INET,
  105. &(session_info->channel_data.modem_data.console_ip),
  106. buffer,
  107. 16));
  108. if (data_len == 14)
  109. {
  110. /* Connection is PPP */
  111. console_port_tmp = session_info->channel_data.lan_data.console_port;
  112. #if WORDS_BIGENDIAN
  113. console_port_tmp = BSWAP_16(console_port_tmp);
  114. #endif
  115. printf(",%d", console_port_tmp);
  116. }
  117. }
  118. printf("\n");
  119. }
  120. /*
  121. * print_session_info_verbose
  122. */
  123. static void
  124. print_session_info_verbose(const struct get_session_info_rsp * session_info,
  125. int data_len)
  126. {
  127. char buffer[18];
  128. uint16_t console_port_tmp;
  129. printf("session handle : %d\n", session_info->session_handle);
  130. printf("slot count : %d\n", session_info->session_slot_count);
  131. printf("active sessions : %d\n", session_info->active_session_count);
  132. if (data_len == 3)
  133. {
  134. /* There is no session data here */
  135. printf("\n");
  136. return;
  137. }
  138. printf("user id : %d\n", session_info->user_id);
  139. printf("privilege level : %s\n",
  140. val2str(session_info->privilege_level, ipmi_privlvl_vals));
  141. printf("session type : %s\n", session_info->auxiliary_data?
  142. "IPMIv2/RMCP+" : "IPMIv1.5");
  143. printf("channel number : 0x%02x\n", session_info->channel_number);
  144. if (data_len == 18)
  145. {
  146. /* We have 802.3 LAN data */
  147. printf("console ip : %s\n",
  148. inet_ntop(AF_INET,
  149. &(session_info->channel_data.lan_data.console_ip),
  150. buffer,
  151. 16));
  152. printf("console mac : %s\n", mac2str(
  153. session_info->channel_data.lan_data.console_mac));
  154. console_port_tmp = session_info->channel_data.lan_data.console_port;
  155. #if WORDS_BIGENDIAN
  156. console_port_tmp = BSWAP_16(console_port_tmp);
  157. #endif
  158. printf("console port : %d\n", console_port_tmp);
  159. }
  160. else if ((data_len == 12) || (data_len == 14))
  161. {
  162. /* Channel async serial/modem */
  163. printf("Session/Channel Activity Type : %s\n",
  164. val2str(session_info->channel_data.modem_data.session_channel_activity_type,
  165. ipmi_channel_activity_type_vals));
  166. printf("Destination selector : %d\n",
  167. session_info->channel_data.modem_data.destination_selector);
  168. printf("console ip : %s\n",
  169. inet_ntop(AF_INET,
  170. &(session_info->channel_data.modem_data.console_ip),
  171. buffer,
  172. 16));
  173. if (data_len == 14)
  174. {
  175. /* Connection is PPP */
  176. console_port_tmp = session_info->channel_data.lan_data.console_port;
  177. #if WORDS_BIGENDIAN
  178. console_port_tmp = BSWAP_16(console_port_tmp);
  179. #endif
  180. printf("console port : %d\n", console_port_tmp);
  181. }
  182. }
  183. printf("\n");
  184. }
  185. static void print_session_info(const struct get_session_info_rsp * session_info,
  186. int data_len)
  187. {
  188. if (csv_output)
  189. print_session_info_csv(session_info, data_len);
  190. else
  191. print_session_info_verbose(session_info, data_len);
  192. }
  193. /*
  194. * ipmi_get_session_info
  195. *
  196. * returns 0 on success
  197. * -1 on error
  198. */
  199. int
  200. ipmi_get_session_info(struct ipmi_intf * intf,
  201. Ipmi_Session_Request_Type session_request_type,
  202. uint32_t id_or_handle)
  203. {
  204. int i, retval = 0;
  205. struct ipmi_rs * rsp;
  206. struct ipmi_rq req;
  207. uint8_t rqdata[5]; // max length of the variable length request
  208. struct get_session_info_rsp session_info;
  209. memset(&req, 0, sizeof(req));
  210. memset(&session_info, 0, sizeof(session_info));
  211. req.msg.netfn = IPMI_NETFN_APP; // 0x06
  212. req.msg.cmd = IPMI_GET_SESSION_INFO; // 0x3D
  213. req.msg.data = rqdata;
  214. switch (session_request_type)
  215. {
  216. case IPMI_SESSION_REQUEST_CURRENT:
  217. case IPMI_SESSION_REQUEST_BY_ID:
  218. case IPMI_SESSION_REQUEST_BY_HANDLE:
  219. switch (session_request_type)
  220. {
  221. case IPMI_SESSION_REQUEST_CURRENT:
  222. rqdata[0] = 0x00;
  223. req.msg.data_len = 1;
  224. break;
  225. case IPMI_SESSION_REQUEST_BY_ID:
  226. rqdata[0] = 0xFF;
  227. rqdata[1] = id_or_handle & 0x000000FF;
  228. rqdata[2] = (id_or_handle >> 8) & 0x000000FF;
  229. rqdata[3] = (id_or_handle >> 16) & 0x000000FF;
  230. rqdata[4] = (id_or_handle >> 24) & 0x000000FF;
  231. req.msg.data_len = 5;
  232. break;
  233. case IPMI_SESSION_REQUEST_BY_HANDLE:
  234. rqdata[0] = 0xFE;
  235. rqdata[1] = (uint8_t)id_or_handle;
  236. req.msg.data_len = 2;
  237. break;
  238. case IPMI_SESSION_REQUEST_ALL:
  239. break;
  240. }
  241. rsp = intf->sendrecv(intf, &req);
  242. if (rsp == NULL)
  243. {
  244. lprintf(LOG_ERR, "Get Session Info command failed");
  245. retval = -1;
  246. }
  247. else if (rsp->ccode > 0)
  248. {
  249. lprintf(LOG_ERR, "Get Session Info command failed: %s",
  250. val2str(rsp->ccode, completion_code_vals));
  251. retval = -1;
  252. }
  253. if (retval < 0)
  254. {
  255. if ((session_request_type == IPMI_SESSION_REQUEST_CURRENT) &&
  256. (strncmp(intf->name, "lan", 3) != 0))
  257. lprintf(LOG_ERR, "It is likely that the channel in use "
  258. "does not support sessions");
  259. }
  260. else
  261. {
  262. memcpy(&session_info, rsp->data, rsp->data_len);
  263. print_session_info(&session_info, rsp->data_len);
  264. }
  265. break;
  266. case IPMI_SESSION_REQUEST_ALL:
  267. req.msg.data_len = 1;
  268. i = 1;
  269. do
  270. {
  271. rqdata[0] = i++;
  272. rsp = intf->sendrecv(intf, &req);
  273. if (rsp == NULL)
  274. {
  275. lprintf(LOG_ERR, "Get Session Info command failed");
  276. retval = -1;
  277. break;
  278. }
  279. else if (rsp->ccode > 0 && rsp->ccode != 0xCC && rsp->ccode != 0xCB)
  280. {
  281. lprintf(LOG_ERR, "Get Session Info command failed: %s",
  282. val2str(rsp->ccode, completion_code_vals));
  283. retval = -1;
  284. break;
  285. }
  286. else if (rsp->data_len < 3)
  287. {
  288. retval = -1;
  289. break;
  290. }
  291. memcpy(&session_info, rsp->data, rsp->data_len);
  292. print_session_info(&session_info, rsp->data_len);
  293. } while (i <= session_info.session_slot_count);
  294. break;
  295. }
  296. return retval;
  297. }
  298. static void
  299. printf_session_usage(void)
  300. {
  301. lprintf(LOG_NOTICE, "Session Commands: info <active | all | id 0xnnnnnnnn | handle 0xnn>");
  302. }
  303. int
  304. ipmi_session_main(struct ipmi_intf * intf, int argc, char ** argv)
  305. {
  306. int retval = 0;
  307. if (argc == 0 || strncmp(argv[0], "help", 4) == 0)
  308. {
  309. printf_session_usage();
  310. }
  311. else if (strncmp(argv[0], "info", 4) == 0)
  312. {
  313. if ((argc < 2) || strncmp(argv[1], "help", 4) == 0)
  314. {
  315. printf_session_usage();
  316. }
  317. else
  318. {
  319. Ipmi_Session_Request_Type session_request_type = 0;
  320. uint32_t id_or_handle = 0;
  321. if (strncmp(argv[1], "active", 6) == 0)
  322. session_request_type = IPMI_SESSION_REQUEST_CURRENT;
  323. else if (strncmp(argv[1], "all", 3) == 0)
  324. session_request_type = IPMI_SESSION_REQUEST_ALL;
  325. else if (strncmp(argv[1], "id", 2) == 0)
  326. {
  327. if (argc >= 3)
  328. {
  329. session_request_type = IPMI_SESSION_REQUEST_BY_ID;
  330. if (str2uint(argv[2], &id_or_handle) != 0) {
  331. lprintf(LOG_ERR, "HEX number expected, but '%s' given.",
  332. argv[2]);
  333. printf_session_usage();
  334. retval = -1;
  335. }
  336. }
  337. else
  338. {
  339. lprintf(LOG_ERR, "Missing id argument");
  340. printf_session_usage();
  341. retval = -1;
  342. }
  343. }
  344. else if (strncmp(argv[1], "handle", 6) == 0)
  345. {
  346. if (argc >= 3)
  347. {
  348. session_request_type = IPMI_SESSION_REQUEST_BY_HANDLE;
  349. if (str2uint(argv[2], &id_or_handle) != 0) {
  350. lprintf(LOG_ERR, "HEX number expected, but '%s' given.",
  351. argv[2]);
  352. printf_session_usage();
  353. retval = -1;
  354. }
  355. }
  356. else
  357. {
  358. lprintf(LOG_ERR, "Missing handle argument");
  359. printf_session_usage();
  360. retval = -1;
  361. }
  362. }
  363. else
  364. {
  365. lprintf(LOG_ERR, "Invalid SESSION info parameter: %s", argv[1]);
  366. printf_session_usage();
  367. retval = -1;
  368. }
  369. if (retval == 0)
  370. retval = ipmi_get_session_info(intf,
  371. session_request_type,
  372. id_or_handle);
  373. }
  374. }
  375. else
  376. {
  377. lprintf(LOG_ERR, "Invalid SESSION command: %s", argv[0]);
  378. printf_session_usage();
  379. retval = -1;
  380. }
  381. return retval;
  382. }