PageRenderTime 82ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 1ms

/OpenIPMI-2.0.18/lib/ipmi_lan.c

#
C | 7041 lines | 5799 code | 902 blank | 340 comment | 1110 complexity | fde67a6e79a3f878053cd89526877d82 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1
  1. /*
  2. * ipmi_lan.c
  3. *
  4. * MontaVista IPMI code for handling IPMI LAN connections
  5. *
  6. * Author: MontaVista Software, Inc.
  7. * Corey Minyard <minyard@mvista.com>
  8. * source@mvista.com
  9. *
  10. * Copyright 2002,2003,2004 MontaVista Software Inc.
  11. *
  12. * This program is free software; you can redistribute it and/or
  13. * modify it under the terms of the GNU Lesser General Public License
  14. * as published by the Free Software Foundation; either version 2 of
  15. * the License, or (at your option) any later version.
  16. *
  17. *
  18. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
  19. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  20. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  21. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  22. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  23. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  24. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  25. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
  26. * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
  27. * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28. *
  29. * You should have received a copy of the GNU Lesser General Public
  30. * License along with this program; if not, write to the Free
  31. * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  32. */
  33. #include <config.h>
  34. #include <sys/types.h>
  35. #include <sys/socket.h>
  36. #include <netinet/in.h>
  37. #include <sys/stat.h>
  38. #include <sys/poll.h>
  39. #include <sys/time.h>
  40. #include <fcntl.h>
  41. #include <stdio.h>
  42. #include <stdlib.h>
  43. #include <unistd.h>
  44. #include <string.h>
  45. #include <netdb.h>
  46. #include <arpa/inet.h>
  47. #include <OpenIPMI/ipmi_conn.h>
  48. #include <OpenIPMI/ipmi_msgbits.h>
  49. #include <OpenIPMI/ipmi_auth.h>
  50. #include <OpenIPMI/ipmi_err.h>
  51. #include <OpenIPMI/ipmi_lan.h>
  52. #include <OpenIPMI/internal/ipmi_event.h>
  53. #include <OpenIPMI/internal/ipmi_int.h>
  54. #include <OpenIPMI/internal/locked_list.h>
  55. #if defined(DEBUG_MSG) || defined(DEBUG_RAWMSG)
  56. static void
  57. dump_hex(void *vdata, int len)
  58. {
  59. unsigned char *data = vdata;
  60. int i;
  61. for (i=0; i<len; i++) {
  62. if ((i != 0) && ((i % 16) == 0)) {
  63. ipmi_log(IPMI_LOG_DEBUG_CONT, "\n ");
  64. }
  65. ipmi_log(IPMI_LOG_DEBUG_CONT, " %2.2x", data[i]);
  66. }
  67. }
  68. #endif
  69. #define LAN_AUDIT_TIMEOUT 10000000
  70. /* Timeout to wait for IPMI responses, in microseconds. For commands
  71. with side effects, we wait 5 seconds, not one. */
  72. #define LAN_RSP_TIMEOUT 1000000
  73. #define LAN_RSP_TIMEOUT_SIDEEFF 5000000
  74. /* # of times to try a message before we fail it. */
  75. #define LAN_RSP_RETRIES 6
  76. /* Number of microseconds of consecutive failures allowed on an IP
  77. before it is considered failed. */
  78. #define IP_FAIL_TIME 7000000
  79. /* Number of consecutive failures that must occur before an IP is
  80. considered failed. */
  81. #define IP_FAIL_COUNT 4
  82. /* The default for the maximum number of messages that are allowed to be
  83. outstanding. This is a pretty conservative number. */
  84. #define DEFAULT_MAX_OUTSTANDING_MSG_COUNT 2
  85. #define MAX_POSSIBLE_OUTSTANDING_MSG_COUNT 63
  86. typedef struct lan_data_s lan_data_t;
  87. typedef struct audit_timer_info_s
  88. {
  89. int cancelled;
  90. ipmi_con_t *ipmi;
  91. } audit_timer_info_t;
  92. typedef struct lan_timer_info_s
  93. {
  94. int cancelled;
  95. ipmi_con_t *ipmi;
  96. os_hnd_timer_id_t *timer;
  97. unsigned int seq;
  98. } lan_timer_info_t;
  99. typedef struct lan_wait_queue_s
  100. {
  101. lan_timer_info_t *info;
  102. ipmi_addr_t addr;
  103. unsigned int addr_len;
  104. ipmi_msg_t msg;
  105. unsigned char data[IPMI_MAX_MSG_LENGTH];
  106. ipmi_ll_rsp_handler_t rsp_handler;
  107. ipmi_msgi_t *rsp_item;
  108. int side_effects;
  109. struct lan_wait_queue_s *next;
  110. } lan_wait_queue_t;
  111. #define MAX_IP_ADDR 2
  112. /* We must keep this number small, if it's too big and a failure
  113. occurs, we will be outside the sequence number before we switch. */
  114. #define SENDS_BETWEEN_IP_SWITCHES 3
  115. /* Because sizeof(sockaddr_in6) > sizeof(sockaddr_in), this structure
  116. * is used as a replacement of struct sockaddr. */
  117. typedef struct sockaddr_ip_s {
  118. union
  119. {
  120. struct sockaddr s_addr;
  121. struct sockaddr_in s_addr4;
  122. #ifdef PF_INET6
  123. struct sockaddr_in6 s_addr6;
  124. #endif
  125. } s_ipsock;
  126. socklen_t ip_addr_len;
  127. } sockaddr_ip_t;
  128. struct ipmi_rmcpp_auth_s
  129. {
  130. lan_data_t *lan;
  131. int addr_num;
  132. uint8_t role;
  133. /* Filled in by the auth algorithm. */
  134. unsigned char my_rand[16];
  135. unsigned int my_rand_len;
  136. unsigned char mgsys_rand[16];
  137. unsigned int mgsys_rand_len;
  138. unsigned char mgsys_guid[16];
  139. unsigned int mgsys_guid_len;
  140. unsigned char sik[20];
  141. unsigned int sik_len;
  142. unsigned char k1[20];
  143. unsigned int k1_len;
  144. unsigned char k2[20];
  145. unsigned int k2_len;
  146. };
  147. typedef struct lan_conn_parms_s
  148. {
  149. unsigned int num_ip_addr;
  150. char *ip_addr_str[MAX_IP_ADDR];
  151. char *ip_port_str[MAX_IP_ADDR];
  152. sockaddr_ip_t ip_addr[MAX_IP_ADDR];
  153. unsigned int authtype;
  154. unsigned int privilege;
  155. unsigned char username[IPMI_USERNAME_MAX];
  156. unsigned int username_len;
  157. unsigned char password[IPMI_PASSWORD_MAX];
  158. unsigned int password_len;
  159. unsigned int conf;
  160. unsigned int integ;
  161. unsigned int auth;
  162. unsigned int name_lookup_only;
  163. unsigned char bmc_key[IPMI_PASSWORD_MAX];
  164. unsigned int bmc_key_len;
  165. } lan_conn_parms_t;
  166. typedef struct lan_link_s lan_link_t;
  167. struct lan_link_s
  168. {
  169. lan_link_t *next, *prev;
  170. lan_data_t *lan;
  171. };
  172. typedef struct lan_fd_s lan_fd_t;
  173. typedef struct lan_stat_info_s
  174. {
  175. #define STAT_RECV_PACKETS 0
  176. #define STAT_XMIT_PACKETS 1
  177. #define STAT_REXMITS 2
  178. #define STAT_TIMED_OUT 3
  179. #define STAT_INVALID_RMCP 4
  180. #define STAT_TOO_SHORT 5
  181. #define STAT_INVALID_AUTH 6
  182. #define STAT_BAD_SESSION_ID 7
  183. #define STAT_AUTH_FAIL 8
  184. #define STAT_DUPLICATES 9
  185. #define STAT_SEQ_OUT_OF_RANGE 10
  186. #define STAT_ASYNC_EVENTS 11
  187. #define STAT_CONN_DOWN 12
  188. #define STAT_CONN_UP 13
  189. #define STAT_BAD_SIZE 14
  190. #define STAT_DECRYPT_FAIL 15
  191. #define STAT_INVALID_PAYLOAD 16
  192. #define STAT_SEQ_ERR 17
  193. #define STAT_RSP_NO_CMD 18
  194. #define NUM_STATS 19
  195. /* Statistics */
  196. void *stats[NUM_STATS];
  197. } lan_stat_info_t;
  198. static const char *lan_stat_names[NUM_STATS] =
  199. {
  200. "lan_recv_packets",
  201. "lan_xmit_packets",
  202. "lan_rexmits",
  203. "lan_timed_out",
  204. "lan_invalid_rmcp",
  205. "lan_too_short",
  206. "lan_invalid_auth",
  207. "lan_bad_session_id",
  208. "lan_auth_fail",
  209. "lan_duplicates",
  210. "lan_seq_out_of_range",
  211. "lan_async_events",
  212. "lan_conn_down",
  213. "lan_conn_up",
  214. "lan_bad_size",
  215. "lan_decrypt_fail",
  216. "lan_invalid_payload",
  217. "lan_seq_err",
  218. "lan_rsp_no_cmd"
  219. };
  220. /* Per-IP specific information. */
  221. typedef struct lan_ip_data_s
  222. {
  223. int working;
  224. unsigned int consecutive_failures;
  225. struct timeval failure_time;
  226. /* For both RMCP and RMCP+. For RMCP+, the session id is the one
  227. I receive and the sequence numbers are the authenticated
  228. ones. */
  229. unsigned char working_authtype;
  230. uint32_t session_id;
  231. uint32_t outbound_seq_num;
  232. uint32_t inbound_seq_num;
  233. uint16_t recv_msg_map;
  234. /* RMCP+ specific info */
  235. uint32_t unauth_out_seq_num;
  236. uint32_t unauth_in_seq_num;
  237. uint16_t unauth_recv_msg_map;
  238. unsigned char working_integ;
  239. unsigned char working_conf;
  240. uint32_t mgsys_session_id;
  241. ipmi_rmcpp_auth_t ainfo;
  242. /* Used to hold the session id before the connection is up. */
  243. uint32_t precon_session_id;
  244. uint32_t precon_mgsys_session_id;
  245. ipmi_rmcpp_confidentiality_t *conf_info;
  246. void *conf_data;
  247. ipmi_rmcpp_integrity_t *integ_info;
  248. void *integ_data;
  249. /* Use for linked-lists of IP addresses. */
  250. lan_link_t ip_link;
  251. } lan_ip_data_t;
  252. #if IPMI_MAX_MSG_LENGTH > 80
  253. # define LAN_MAX_RAW_MSG IPMI_MAX_MSG_LENGTH
  254. #else
  255. # define LAN_MAX_RAW_MSG 80 /* Enough to hold the rmcp+ session messages */
  256. #endif
  257. struct lan_data_s
  258. {
  259. unsigned int refcount;
  260. unsigned int users;
  261. ipmi_con_t *ipmi;
  262. lan_fd_t *fd;
  263. int fd_slot;
  264. unsigned char slave_addr[MAX_IPMI_USED_CHANNELS];
  265. int is_active;
  266. /* Have we already been started? */
  267. int started;
  268. /* Are we currently in cleanup? Don't allow any outgoing messages. */
  269. int in_cleanup;
  270. /* Protects modifiecations to working, curr_ip_addr, RMCP
  271. sequence numbers, the con_change_handler, and other
  272. connection-related data. Note that if the seq_num_lock must
  273. also be held, it must be locked before this lock. */
  274. ipmi_lock_t *ip_lock;
  275. /* If 0, we don't have a connection to the BMC right now. */
  276. int connected;
  277. /* If 0, we have not yet initialized */
  278. int initialized;
  279. /* If 0, the OEM handlers have not been called. */
  280. int oem_conn_handlers_called;
  281. /* Number of packets sent on the connection. Used to track when
  282. to switch between IP addresses. */
  283. unsigned int num_sends;
  284. /* The IP address we are currently using. */
  285. unsigned int curr_ip_addr;
  286. /* Data about each IP address */
  287. lan_ip_data_t ip[MAX_IP_ADDR];
  288. /* We keep a session on each LAN connection. I don't think all
  289. systems require that, but it's safer. */
  290. /* From the get channel auth */
  291. unsigned char oem_iana[3];
  292. unsigned char oem_aux;
  293. /* Parms we were configured with. */
  294. lan_conn_parms_t cparm;
  295. /* IPMI LAN 1.5 specific info. */
  296. unsigned char chosen_authtype;
  297. unsigned char challenge_string[16];
  298. ipmi_authdata_t authdata;
  299. /* RMCP+ specific info */
  300. unsigned int use_two_keys : 1;
  301. struct {
  302. unsigned int inuse : 1;
  303. ipmi_addr_t addr;
  304. unsigned int addr_len;
  305. ipmi_msg_t msg;
  306. unsigned char data[LAN_MAX_RAW_MSG];
  307. ipmi_ll_rsp_handler_t rsp_handler;
  308. ipmi_msgi_t *rsp_item;
  309. int use_orig_addr;
  310. ipmi_addr_t orig_addr;
  311. unsigned int orig_addr_len;
  312. os_hnd_timer_id_t *timer;
  313. lan_timer_info_t *timer_info;
  314. int retries_left;
  315. int side_effects;
  316. /* If -1, just use the normal algorithm. If not -1, force to
  317. this address. */
  318. int addr_num;
  319. /* The number of the last IP address sent on. */
  320. int last_ip_num;
  321. } seq_table[64];
  322. ipmi_lock_t *seq_num_lock;
  323. /* The current sequence number. Note that we reserve sequence
  324. number 0 for our own neferous purposes. */
  325. unsigned int last_seq;
  326. /* The number of messages that are outstanding with the remote
  327. MC. */
  328. unsigned int outstanding_msg_count;
  329. /* The maximum number of outstanding messages. This must NEVER be
  330. larger than 63 (64 sequence numbers minus 1 for our reserved
  331. sequence zero. */
  332. unsigned int max_outstanding_msg_count;
  333. /* List of messages waiting to be sent. */
  334. lan_wait_queue_t *wait_q, *wait_q_tail;
  335. locked_list_t *event_handlers;
  336. os_hnd_timer_id_t *audit_timer;
  337. audit_timer_info_t *audit_info;
  338. /* Handles connection shutdown reporting. */
  339. ipmi_ll_con_closed_cb close_done;
  340. void *close_cb_data;
  341. /* This lock is used to assure that the conn changes occur in
  342. proper order. The user code is called with this lock held, but
  343. it should be harmless to the user as this is the only use for
  344. it. But the user cannot do a wait on I/O in the handler. */
  345. ipmi_lock_t *con_change_lock;
  346. locked_list_t *con_change_handlers;
  347. locked_list_t *ipmb_change_handlers;
  348. lan_link_t link;
  349. locked_list_t *lan_stat_list;
  350. };
  351. /************************************************************************
  352. *
  353. * Authentication and encryption information and functions.
  354. *
  355. ***********************************************************************/
  356. extern ipmi_payload_t _ipmi_payload;
  357. static int
  358. open_format_msg(ipmi_con_t *ipmi,
  359. const ipmi_addr_t *addr,
  360. unsigned int addr_len,
  361. const ipmi_msg_t *msg,
  362. unsigned char *out_data,
  363. unsigned int *out_data_len,
  364. int *out_of_session,
  365. unsigned char seq)
  366. {
  367. unsigned char *tmsg = out_data;
  368. if (msg->data_len > *out_data_len)
  369. return E2BIG;
  370. memcpy(tmsg, msg->data, msg->data_len);
  371. tmsg[0] = seq; /* We use the message tag for the sequence # */
  372. *out_of_session = 1;
  373. *out_data_len = msg->data_len;
  374. return 0;
  375. }
  376. static int
  377. open_get_recv_seq(ipmi_con_t *ipmi,
  378. unsigned char *data,
  379. unsigned int data_len,
  380. unsigned char *seq)
  381. {
  382. if (data_len < 1) { /* Minimum size of an IPMI msg. */
  383. if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
  384. ipmi_log(IPMI_LOG_DEBUG,
  385. "%sDropped message because too small(7)",
  386. IPMI_CONN_NAME(ipmi));
  387. return EINVAL;
  388. }
  389. *seq = data[0];
  390. return 0;
  391. }
  392. static int
  393. open_handle_recv(ipmi_con_t *ipmi,
  394. ipmi_msgi_t *rspi,
  395. ipmi_addr_t *orig_addr,
  396. unsigned int orig_addr_len,
  397. ipmi_msg_t *orig_msg,
  398. unsigned char *data,
  399. unsigned int data_len)
  400. {
  401. ipmi_msg_t *msg = &(rspi->msg);
  402. if (data_len > sizeof(rspi->data))
  403. return E2BIG;
  404. memcpy(rspi->data, data, data_len);
  405. msg->data = rspi->data;
  406. msg->data_len = data_len;
  407. return 0;
  408. }
  409. static void
  410. open_handle_recv_async(ipmi_con_t *ipmi,
  411. unsigned char *tmsg,
  412. unsigned int data_len)
  413. {
  414. }
  415. static int
  416. open_get_msg_tag(unsigned char *tmsg,
  417. unsigned int data_len,
  418. unsigned char *tag)
  419. {
  420. if (data_len < 8)
  421. return EINVAL;
  422. *tag = ipmi_get_uint32(tmsg+4) - 1; /* session id */
  423. return 0;
  424. }
  425. static ipmi_payload_t open_payload =
  426. { open_format_msg, open_get_recv_seq, open_handle_recv,
  427. open_handle_recv_async, open_get_msg_tag };
  428. static ipmi_payload_t *payloads[64] =
  429. {
  430. &_ipmi_payload,
  431. [IPMI_RMCPP_PAYLOAD_TYPE_OPEN_SESSION_REQUEST] = &open_payload,
  432. [IPMI_RMCPP_PAYLOAD_TYPE_OPEN_SESSION_RESPONSE] = &open_payload
  433. };
  434. typedef struct payload_entry_s payload_entry_t;
  435. struct payload_entry_s
  436. {
  437. unsigned int payload_type;
  438. unsigned char iana[3];
  439. unsigned int payload_id;
  440. ipmi_payload_t *payload;
  441. payload_entry_t *next;
  442. };
  443. /* Note that we only add payloads to the head, so no lock is required
  444. except for addition. */
  445. static ipmi_lock_t *lan_payload_lock = NULL;
  446. payload_entry_t *oem_payload_list = NULL;
  447. int
  448. ipmi_rmcpp_register_payload(unsigned int payload_type,
  449. ipmi_payload_t *payload)
  450. {
  451. if ((payload_type == IPMI_RMCPP_PAYLOAD_TYPE_IPMI)
  452. || (payload_type == IPMI_RMCPP_PAYLOAD_TYPE_OEM_EXPLICIT)
  453. || (payload_type == IPMI_RMCPP_PAYLOAD_TYPE_OPEN_SESSION_REQUEST)
  454. || (payload_type == IPMI_RMCPP_PAYLOAD_TYPE_OPEN_SESSION_RESPONSE)
  455. || (payload_type >= 64)
  456. || ((payload_type >= 0x20) && (payload_type <= 0x27))) /* No OEM here*/
  457. {
  458. return EINVAL;
  459. }
  460. ipmi_lock(lan_payload_lock);
  461. if (payloads[payload_type] && payload) {
  462. ipmi_unlock(lan_payload_lock);
  463. return EAGAIN;
  464. }
  465. payloads[payload_type] = payload;
  466. ipmi_unlock(lan_payload_lock);
  467. return 0;
  468. }
  469. int
  470. ipmi_rmcpp_register_oem_payload(unsigned int payload_type,
  471. unsigned char iana[3],
  472. unsigned int payload_id,
  473. ipmi_payload_t *payload)
  474. {
  475. payload_entry_t *e;
  476. payload_entry_t *c;
  477. e = ipmi_mem_alloc(sizeof(*e));
  478. if (!e)
  479. return ENOMEM;
  480. e->payload_type = payload_type;
  481. memcpy(e->iana, iana, 3);
  482. if (payload_type == IPMI_RMCPP_PAYLOAD_TYPE_OEM_EXPLICIT)
  483. e->payload_id = payload_id;
  484. else
  485. e->payload_id = 0;
  486. e->payload = payload;
  487. ipmi_lock(lan_payload_lock);
  488. c = oem_payload_list;
  489. while (c) {
  490. if ((c->payload_type == payload_type)
  491. && (memcmp(c->iana, iana, 3) == 0)
  492. && (c->payload_id == payload_id))
  493. {
  494. ipmi_unlock(lan_payload_lock);
  495. ipmi_mem_free(e);
  496. return EAGAIN;
  497. }
  498. c = c->next;
  499. }
  500. e->next = oem_payload_list;
  501. oem_payload_list = e;
  502. ipmi_unlock(lan_payload_lock);
  503. return 0;
  504. }
  505. static ipmi_lock_t *lan_auth_lock = NULL;
  506. typedef struct auth_entry_s auth_entry_t;
  507. struct auth_entry_s
  508. {
  509. unsigned int auth_num;
  510. unsigned char iana[3];
  511. ipmi_rmcpp_authentication_t *auth;
  512. auth_entry_t *next;
  513. };
  514. static auth_entry_t *oem_auth_list = NULL;
  515. static ipmi_rmcpp_authentication_t *auths[64];
  516. int
  517. ipmi_rmcpp_register_authentication(unsigned int auth_num,
  518. ipmi_rmcpp_authentication_t *auth)
  519. {
  520. if (auth_num >= 64)
  521. return EINVAL;
  522. if (auths[auth_num] && auth)
  523. return EAGAIN;
  524. auths[auth_num] = auth;
  525. return 0;
  526. }
  527. int
  528. ipmi_rmcpp_register_oem_authentication(unsigned int auth_num,
  529. unsigned char iana[3],
  530. ipmi_rmcpp_authentication_t *auth)
  531. {
  532. auth_entry_t *e;
  533. auth_entry_t *c;
  534. e = ipmi_mem_alloc(sizeof(*e));
  535. if (!e)
  536. return ENOMEM;
  537. e->auth_num = auth_num;
  538. memcpy(e->iana, iana, 3);
  539. e->auth = auth;
  540. ipmi_lock(lan_auth_lock);
  541. c = oem_auth_list;
  542. while (c) {
  543. if ((c->auth_num == auth_num)
  544. && (memcmp(c->iana, iana, 3) == 0))
  545. {
  546. ipmi_unlock(lan_auth_lock);
  547. ipmi_mem_free(e);
  548. return EAGAIN;
  549. }
  550. }
  551. e->next = oem_auth_list;
  552. oem_auth_list = e;
  553. ipmi_unlock(lan_auth_lock);
  554. return 0;
  555. }
  556. typedef struct conf_entry_s conf_entry_t;
  557. struct conf_entry_s
  558. {
  559. unsigned int conf_num;
  560. unsigned char iana[3];
  561. ipmi_rmcpp_confidentiality_t *conf;
  562. conf_entry_t *next;
  563. };
  564. static conf_entry_t *oem_conf_list = NULL;
  565. static int
  566. conf_none_init(ipmi_con_t *ipmi, ipmi_rmcpp_auth_t *ainfo, void **conf_data)
  567. {
  568. *conf_data = NULL;
  569. return 0;
  570. }
  571. static void
  572. conf_none_free(ipmi_con_t *ipmi, void *conf_data)
  573. {
  574. }
  575. static int
  576. conf_none_encrypt(ipmi_con_t *ipmi,
  577. void *conf_data,
  578. unsigned char **payload,
  579. unsigned int *header_len,
  580. unsigned int *payload_len,
  581. unsigned int *max_payload_len)
  582. {
  583. return 0;
  584. }
  585. static int
  586. conf_none_decrypt(ipmi_con_t *ipmi,
  587. void *conf_data,
  588. unsigned char **payload,
  589. unsigned int *payload_len)
  590. {
  591. return 0;
  592. }
  593. static ipmi_rmcpp_confidentiality_t conf_none =
  594. { conf_none_init, conf_none_free, conf_none_encrypt, conf_none_decrypt};
  595. static ipmi_rmcpp_confidentiality_t *confs[64] =
  596. {
  597. &conf_none
  598. };
  599. int ipmi_rmcpp_register_confidentiality(unsigned int conf_num,
  600. ipmi_rmcpp_confidentiality_t *conf)
  601. {
  602. if ((conf_num == 0) || (conf_num >= 64))
  603. return EINVAL;
  604. if (confs[conf_num] && conf)
  605. return EAGAIN;
  606. confs[conf_num] = conf;
  607. return 0;
  608. }
  609. int
  610. ipmi_rmcpp_register_oem_confidentiality(unsigned int conf_num,
  611. unsigned char iana[3],
  612. ipmi_rmcpp_confidentiality_t *conf)
  613. {
  614. conf_entry_t *e;
  615. conf_entry_t *c;
  616. e = ipmi_mem_alloc(sizeof(*e));
  617. if (!e)
  618. return ENOMEM;
  619. e->conf_num = conf_num;
  620. memcpy(e->iana, iana, 3);
  621. e->conf = conf;
  622. ipmi_lock(lan_auth_lock);
  623. c = oem_conf_list;
  624. while (c) {
  625. if ((c->conf_num == conf_num)
  626. && (memcmp(c->iana, iana, 3) == 0))
  627. {
  628. ipmi_unlock(lan_auth_lock);
  629. ipmi_mem_free(e);
  630. return EAGAIN;
  631. }
  632. }
  633. e->next = oem_conf_list;
  634. oem_conf_list = e;
  635. ipmi_unlock(lan_auth_lock);
  636. return 0;
  637. }
  638. typedef struct integ_entry_s integ_entry_t;
  639. struct integ_entry_s
  640. {
  641. unsigned int integ_num;
  642. unsigned char iana[3];
  643. ipmi_rmcpp_integrity_t *integ;
  644. integ_entry_t *next;
  645. };
  646. static integ_entry_t *oem_integ_list = NULL;
  647. static int
  648. integ_none_init(ipmi_con_t *ipmi,
  649. ipmi_rmcpp_auth_t *ainfo,
  650. void **integ_data)
  651. {
  652. *integ_data = NULL;
  653. return 0;
  654. }
  655. static void
  656. integ_none_free(ipmi_con_t *ipmi,
  657. void *integ_data)
  658. {
  659. }
  660. static int
  661. integ_none_pad(ipmi_con_t *ipmi,
  662. void *integ_data,
  663. unsigned char *payload,
  664. unsigned int *payload_len,
  665. unsigned int max_payload_len)
  666. {
  667. return 0;
  668. }
  669. static int
  670. integ_none_add(ipmi_con_t *ipmi,
  671. void *integ_data,
  672. unsigned char *payload,
  673. unsigned int *payload_len,
  674. unsigned int max_payload_len)
  675. {
  676. return 0;
  677. }
  678. static int
  679. integ_none_check(ipmi_con_t *ipmi,
  680. void *integ_data,
  681. unsigned char *payload,
  682. unsigned int payload_len,
  683. unsigned int total_len)
  684. {
  685. return 0;
  686. }
  687. static ipmi_rmcpp_integrity_t integ_none =
  688. { integ_none_init, integ_none_free, integ_none_pad, integ_none_add,
  689. integ_none_check };
  690. static ipmi_rmcpp_integrity_t *integs[64] =
  691. {
  692. &integ_none
  693. };
  694. int ipmi_rmcpp_register_integrity(unsigned int integ_num,
  695. ipmi_rmcpp_integrity_t *integ)
  696. {
  697. if ((integ_num == 0) || (integ_num >= 64))
  698. return EINVAL;
  699. if (integs[integ_num] && integ)
  700. return EAGAIN;
  701. integs[integ_num] = integ;
  702. return 0;
  703. }
  704. int
  705. ipmi_rmcpp_register_oem_integrity(unsigned int integ_num,
  706. unsigned char iana[3],
  707. ipmi_rmcpp_integrity_t *integ)
  708. {
  709. integ_entry_t *e;
  710. integ_entry_t *c;
  711. e = ipmi_mem_alloc(sizeof(*e));
  712. if (!e)
  713. return ENOMEM;
  714. e->integ_num = integ_num;
  715. memcpy(e->iana, iana, 3);
  716. e->integ = integ;
  717. ipmi_lock(lan_auth_lock);
  718. c = oem_integ_list;
  719. while (c) {
  720. if ((c->integ_num == integ_num)
  721. && (memcmp(c->iana, iana, 3) == 0))
  722. {
  723. ipmi_unlock(lan_auth_lock);
  724. ipmi_mem_free(e);
  725. return EAGAIN;
  726. }
  727. }
  728. e->next = oem_integ_list;
  729. oem_integ_list = e;
  730. ipmi_unlock(lan_auth_lock);
  731. return 0;
  732. }
  733. uint32_t
  734. ipmi_rmcpp_auth_get_my_session_id(ipmi_rmcpp_auth_t *ainfo)
  735. {
  736. return ainfo->lan->ip[ainfo->addr_num].precon_session_id;
  737. }
  738. uint32_t
  739. ipmi_rmcpp_auth_get_mgsys_session_id(ipmi_rmcpp_auth_t *ainfo)
  740. {
  741. return ainfo->lan->ip[ainfo->addr_num].precon_mgsys_session_id;
  742. }
  743. uint8_t
  744. ipmi_rmcpp_auth_get_role(ipmi_rmcpp_auth_t *ainfo)
  745. {
  746. return ainfo->role;
  747. }
  748. const unsigned char *
  749. ipmi_rmcpp_auth_get_username(ipmi_rmcpp_auth_t *ainfo,
  750. unsigned int *max_len)
  751. {
  752. *max_len = 16;
  753. return ainfo->lan->cparm.username;
  754. }
  755. unsigned int
  756. ipmi_rmcpp_auth_get_username_len(ipmi_rmcpp_auth_t *ainfo)
  757. {
  758. return ainfo->lan->cparm.username_len;
  759. }
  760. const unsigned char *
  761. ipmi_rmcpp_auth_get_password(ipmi_rmcpp_auth_t *ainfo,
  762. unsigned int *max_len)
  763. {
  764. *max_len = 20;
  765. return ainfo->lan->cparm.password;
  766. }
  767. unsigned int
  768. ipmi_rmcpp_auth_get_password_len(ipmi_rmcpp_auth_t *ainfo)
  769. {
  770. return ainfo->lan->cparm.password_len;
  771. }
  772. int
  773. ipmi_rmcpp_auth_get_use_two_keys(ipmi_rmcpp_auth_t *ainfo)
  774. {
  775. return ainfo->lan->use_two_keys;
  776. }
  777. const unsigned char *
  778. ipmi_rmcpp_auth_get_bmc_key(ipmi_rmcpp_auth_t *ainfo,
  779. unsigned int *max_len)
  780. {
  781. *max_len = 20;
  782. if (ainfo->lan->use_two_keys)
  783. return ainfo->lan->cparm.bmc_key;
  784. else
  785. return ainfo->lan->cparm.password;
  786. }
  787. unsigned int
  788. ipmi_rmcpp_auth_get_bmc_key_len(ipmi_rmcpp_auth_t *ainfo)
  789. {
  790. if (ainfo->lan->use_two_keys)
  791. return ainfo->lan->cparm.bmc_key_len;
  792. else
  793. return ainfo->lan->cparm.password_len;
  794. }
  795. /* From the get channel auth. */
  796. const unsigned char *
  797. ipmi_rmcpp_auth_get_oem_iana(ipmi_rmcpp_auth_t *ainfo,
  798. unsigned int *len)
  799. {
  800. *len = 3;
  801. return ainfo->lan->oem_iana;
  802. }
  803. unsigned char
  804. ipmi_rmcpp_auth_get_oem_aux(ipmi_rmcpp_auth_t *ainfo)
  805. {
  806. return ainfo->lan->oem_aux;
  807. }
  808. /* Should be filled in by the auth algorithm. */
  809. unsigned char *
  810. ipmi_rmcpp_auth_get_my_rand(ipmi_rmcpp_auth_t *ainfo,
  811. unsigned int *max_len)
  812. {
  813. *max_len = 16;
  814. return ainfo->my_rand;
  815. }
  816. unsigned int
  817. ipmi_rmcpp_auth_get_my_rand_len(ipmi_rmcpp_auth_t *ainfo)
  818. {
  819. return ainfo->my_rand_len;
  820. }
  821. void
  822. ipmi_rmcpp_auth_set_my_rand_len(ipmi_rmcpp_auth_t *ainfo,
  823. unsigned int length)
  824. {
  825. ainfo->my_rand_len = length;
  826. }
  827. unsigned char *
  828. ipmi_rmcpp_auth_get_mgsys_rand(ipmi_rmcpp_auth_t *ainfo,
  829. unsigned int *max_len)
  830. {
  831. *max_len = 16;
  832. return ainfo->mgsys_rand;
  833. }
  834. unsigned int
  835. ipmi_rmcpp_auth_get_mgsys_rand_len(ipmi_rmcpp_auth_t *ainfo)
  836. {
  837. return ainfo->mgsys_rand_len;
  838. }
  839. void
  840. ipmi_rmcpp_auth_set_mgsys_rand_len(ipmi_rmcpp_auth_t *ainfo,
  841. unsigned int length)
  842. {
  843. ainfo->mgsys_rand_len = length;
  844. }
  845. unsigned char *
  846. ipmi_rmcpp_auth_get_mgsys_guid(ipmi_rmcpp_auth_t *ainfo,
  847. unsigned int *max_len)
  848. {
  849. *max_len = 16;
  850. return ainfo->mgsys_guid;
  851. }
  852. unsigned int
  853. ipmi_rmcpp_auth_get_mgsys_guid_len(ipmi_rmcpp_auth_t *ainfo)
  854. {
  855. return ainfo->mgsys_guid_len;
  856. }
  857. void
  858. ipmi_rmcpp_auth_set_mgsys_guid_len(ipmi_rmcpp_auth_t *ainfo,
  859. unsigned int length)
  860. {
  861. ainfo->mgsys_guid_len = length;
  862. }
  863. unsigned char *
  864. ipmi_rmcpp_auth_get_sik(ipmi_rmcpp_auth_t *ainfo,
  865. unsigned int *max_len)
  866. {
  867. *max_len = 20;
  868. return ainfo->sik;
  869. }
  870. unsigned int
  871. ipmi_rmcpp_auth_get_sik_len(ipmi_rmcpp_auth_t *ainfo)
  872. {
  873. return ainfo->sik_len;
  874. }
  875. void
  876. ipmi_rmcpp_auth_set_sik_len(ipmi_rmcpp_auth_t *ainfo,
  877. unsigned int length)
  878. {
  879. ainfo->sik_len = length;
  880. }
  881. unsigned char *
  882. ipmi_rmcpp_auth_get_k1(ipmi_rmcpp_auth_t *ainfo,
  883. unsigned int *max_len)
  884. {
  885. *max_len = 20;
  886. return ainfo->k1;
  887. }
  888. unsigned int
  889. ipmi_rmcpp_auth_get_k1_len(ipmi_rmcpp_auth_t *ainfo)
  890. {
  891. return ainfo->k1_len;
  892. }
  893. void
  894. ipmi_rmcpp_auth_set_k1_len(ipmi_rmcpp_auth_t *ainfo,
  895. unsigned int length)
  896. {
  897. ainfo->k1_len = length;
  898. }
  899. unsigned char *
  900. ipmi_rmcpp_auth_get_k2(ipmi_rmcpp_auth_t *ainfo,
  901. unsigned int *max_len)
  902. {
  903. *max_len = 20;
  904. return ainfo->k2;
  905. }
  906. unsigned int
  907. ipmi_rmcpp_auth_get_k2_len(ipmi_rmcpp_auth_t *ainfo)
  908. {
  909. return ainfo->k2_len;
  910. }
  911. void
  912. ipmi_rmcpp_auth_set_k2_len(ipmi_rmcpp_auth_t *ainfo,
  913. unsigned int length)
  914. {
  915. ainfo->k2_len = length;
  916. }
  917. static void check_command_queue(ipmi_con_t *ipmi, lan_data_t *lan);
  918. static int send_auth_cap(ipmi_con_t *ipmi, lan_data_t *lan, int addr_num,
  919. int force_ipmiv15);
  920. static os_handler_t *lan_os_hnd;
  921. #define MAX_CONS_PER_FD 32
  922. struct lan_fd_s
  923. {
  924. int fd;
  925. os_hnd_fd_id_t *fd_wait_id;
  926. unsigned int cons_in_use;
  927. lan_data_t *lan[MAX_CONS_PER_FD];
  928. lan_fd_t *next, *prev;
  929. ipmi_lock_t *con_lock;
  930. /* Main list info. */
  931. ipmi_lock_t *lock;
  932. lan_fd_t **free_list;
  933. lan_fd_t *list;
  934. };
  935. /* This is a list, but the only searching is to find an fd with a free
  936. slot (when creating a new lan). This is O(1) because the first
  937. entry is guaranteed to have a free slot if any have free slots.
  938. Note that once one of these is created, it is never destroyed
  939. (destruction is very difficult because of the race conditions). */
  940. static ipmi_lock_t *fd_list_lock = NULL;
  941. static lan_fd_t fd_list;
  942. static lan_fd_t *fd_free_list;
  943. #ifdef PF_INET6
  944. static ipmi_lock_t *fd6_list_lock = NULL;
  945. static lan_fd_t fd6_list;
  946. static lan_fd_t *fd6_free_list;
  947. #endif
  948. static void data_handler(int fd,
  949. void *cb_data,
  950. os_hnd_fd_id_t *id);
  951. static int
  952. lan_addr_same(sockaddr_ip_t *a1, sockaddr_ip_t *a2)
  953. {
  954. if (a1->ip_addr_len != a2->ip_addr_len)
  955. return 0;
  956. if (a1->s_ipsock.s_addr.sa_family != a2->s_ipsock.s_addr.sa_family) {
  957. if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
  958. ipmi_log(IPMI_LOG_DEBUG, "Address family mismatch: %d %d",
  959. a1->s_ipsock.s_addr.sa_family,
  960. a2->s_ipsock.s_addr.sa_family);
  961. return 0;
  962. }
  963. switch (a1->s_ipsock.s_addr.sa_family) {
  964. case PF_INET:
  965. {
  966. struct sockaddr_in *ip1 = &a1->s_ipsock.s_addr4;
  967. struct sockaddr_in *ip2 = &a2->s_ipsock.s_addr4;
  968. if ((ip1->sin_port == ip2->sin_port)
  969. && (ip1->sin_addr.s_addr == ip2->sin_addr.s_addr))
  970. return 1;
  971. }
  972. break;
  973. #ifdef PF_INET6
  974. case PF_INET6:
  975. {
  976. struct sockaddr_in6 *ip1 = &a1->s_ipsock.s_addr6;
  977. struct sockaddr_in6 *ip2 = &a2->s_ipsock.s_addr6;
  978. if ((ip1->sin6_port == ip2->sin6_port)
  979. && (bcmp(ip1->sin6_addr.s6_addr, ip2->sin6_addr.s6_addr,
  980. sizeof(struct in6_addr)) == 0))
  981. return 1;
  982. }
  983. break;
  984. #endif
  985. default:
  986. ipmi_log(IPMI_LOG_ERR_INFO,
  987. "ipmi_lan: Unknown protocol family: 0x%x",
  988. a1->s_ipsock.s_addr.sa_family);
  989. break;
  990. }
  991. return 0;
  992. }
  993. static void
  994. move_to_lan_list_end(lan_fd_t *item)
  995. {
  996. lan_fd_t *list = item->list;
  997. item->next->prev = item->prev;
  998. item->prev->next = item->next;
  999. item->next = list;
  1000. item->prev = list->prev;
  1001. list->prev->next = item;
  1002. list->prev = item;
  1003. }
  1004. static void
  1005. move_to_lan_list_head(lan_fd_t *item)
  1006. {
  1007. lan_fd_t *list = item->list;
  1008. item->next->prev = item->prev;
  1009. item->prev->next = item->next;
  1010. item->next = list->next;
  1011. item->prev = list;
  1012. list->next->prev = item;
  1013. list->next = item;
  1014. }
  1015. static lan_fd_t *
  1016. find_free_lan_fd(int family, lan_data_t *lan, int *slot)
  1017. {
  1018. ipmi_lock_t *lock;
  1019. lan_fd_t *list, *item;
  1020. lan_fd_t **free_list;
  1021. int rv;
  1022. int i;
  1023. if (family == PF_INET) {
  1024. lock = fd_list_lock;
  1025. list = &fd_list;
  1026. free_list = &fd_free_list;
  1027. }
  1028. #ifdef PF_INET6
  1029. else if (family == PF_INET6) {
  1030. lock = fd6_list_lock;
  1031. list = &fd6_list;
  1032. free_list = &fd6_free_list;
  1033. }
  1034. #endif
  1035. else {
  1036. return NULL;
  1037. }
  1038. ipmi_lock(lock);
  1039. item = list->next;
  1040. retry:
  1041. if (item->cons_in_use < MAX_CONS_PER_FD) {
  1042. int tslot = -1;
  1043. /* Got an entry with a slot, just reuse it. */
  1044. for (i=0; i<MAX_CONS_PER_FD; i++) {
  1045. if (item->lan[i]) {
  1046. /* Check for a matching IP address. Can't have two
  1047. systems with the same address in the same fd entry. */
  1048. unsigned int j, k;
  1049. lan_data_t *l = item->lan[i];
  1050. for (j=0; j<l->cparm.num_ip_addr; j++) {
  1051. for (k=0; k<lan->cparm.num_ip_addr; k++) {
  1052. if (lan_addr_same(&l->cparm.ip_addr[j],
  1053. &lan->cparm.ip_addr[k]))
  1054. {
  1055. /* Found the same address in the same
  1056. lan_data file. Try another one. */
  1057. item = item->next;
  1058. goto retry;
  1059. }
  1060. }
  1061. }
  1062. } else if (tslot < 0)
  1063. tslot = i;
  1064. }
  1065. if (tslot < 0) {
  1066. lan_fd_t *next = item->next;
  1067. /* Can't happen, but log and fix it up. */
  1068. ipmi_log(IPMI_LOG_SEVERE, "ipmi_lan.c: Internal error, count"
  1069. " in lan fd list item incorrect, but we can recover.");
  1070. item->cons_in_use = MAX_CONS_PER_FD;
  1071. move_to_lan_list_end(item);
  1072. item = next;
  1073. goto retry;
  1074. }
  1075. item->cons_in_use++;
  1076. item->lan[tslot] = lan;
  1077. *slot = tslot;
  1078. if (item->cons_in_use == MAX_CONS_PER_FD)
  1079. /* Out of connections in this item, move it to the end of
  1080. the list. */
  1081. move_to_lan_list_end(item);
  1082. } else {
  1083. /* No free entries, create one */
  1084. if (*free_list) {
  1085. /* Pull them off the free list first. */
  1086. item = *free_list;
  1087. *free_list = item->next;
  1088. } else {
  1089. item = ipmi_mem_alloc(sizeof(*item));
  1090. if (item) {
  1091. memset(item, 0, sizeof(*item));
  1092. rv = ipmi_create_global_lock(&item->con_lock);
  1093. if (rv) {
  1094. ipmi_mem_free(item);
  1095. goto out_unlock;
  1096. }
  1097. item->lock = lock;
  1098. item->free_list = free_list;
  1099. item->list = list;
  1100. }
  1101. }
  1102. if (!item)
  1103. goto out_unlock;
  1104. item->next = item;
  1105. item->prev = item;
  1106. item->fd = socket(family, SOCK_DGRAM, IPPROTO_UDP);
  1107. if (item->fd == -1) {
  1108. item->next = *free_list;
  1109. *free_list = item;
  1110. item = NULL;
  1111. goto out_unlock;
  1112. }
  1113. /* Bind is not necessary, we don't care what port we are. */
  1114. /* We want it to be non-blocking. */
  1115. rv = fcntl(item->fd, F_SETFL, O_NONBLOCK);
  1116. if (rv) {
  1117. close(item->fd);
  1118. item->next = *free_list;
  1119. *free_list = item;
  1120. item = NULL;
  1121. goto out_unlock;
  1122. }
  1123. rv = lan_os_hnd->add_fd_to_wait_for(lan_os_hnd,
  1124. item->fd,
  1125. data_handler,
  1126. item,
  1127. NULL,
  1128. &(item->fd_wait_id));
  1129. if (rv) {
  1130. close(item->fd);
  1131. item->next = *free_list;
  1132. *free_list = item;
  1133. item = NULL;
  1134. goto out_unlock;
  1135. }
  1136. item->cons_in_use++;
  1137. item->lan[0] = lan;
  1138. *slot = 0;
  1139. /* This will have free items, put it at the head of the list. */
  1140. move_to_lan_list_head(item);
  1141. }
  1142. out_unlock:
  1143. ipmi_unlock(lock);
  1144. return item;
  1145. }
  1146. static void
  1147. release_lan_fd(lan_fd_t *item, int slot)
  1148. {
  1149. ipmi_lock(item->lock);
  1150. item->lan[slot] = NULL;
  1151. item->cons_in_use--;
  1152. if (item->cons_in_use == 0) {
  1153. lan_os_hnd->remove_fd_to_wait_for(lan_os_hnd, item->fd_wait_id);
  1154. close(item->fd);
  1155. item->next->prev = item->prev;
  1156. item->prev->next = item->next;
  1157. item->next = *(item->free_list);
  1158. *(item->free_list) = item;
  1159. } else {
  1160. /* This has free connections, move it to the head of the
  1161. list. */
  1162. move_to_lan_list_head(item);
  1163. }
  1164. ipmi_unlock(item->lock);
  1165. }
  1166. /*
  1167. * We keep two hash tables, one by IP address and one by connection
  1168. * address.
  1169. */
  1170. #define LAN_HASH_SIZE 256
  1171. #define LAN_HASH_SHIFT 6
  1172. static ipmi_lock_t *lan_list_lock = NULL;
  1173. static lan_link_t lan_list[LAN_HASH_SIZE];
  1174. static lan_link_t lan_ip_list[LAN_HASH_SIZE];
  1175. static unsigned int
  1176. hash_lan(const ipmi_con_t *ipmi)
  1177. {
  1178. unsigned int idx;
  1179. idx = (((unsigned long) ipmi)
  1180. >> (sizeof(unsigned long) + LAN_HASH_SHIFT));
  1181. idx %= LAN_HASH_SIZE;
  1182. return idx;
  1183. }
  1184. static int
  1185. hash_lan_addr(const struct sockaddr *addr)
  1186. {
  1187. int idx;
  1188. switch (addr->sa_family)
  1189. {
  1190. case PF_INET:
  1191. {
  1192. struct sockaddr_in *iaddr = (struct sockaddr_in *) addr;
  1193. idx = ntohl(iaddr->sin_addr.s_addr) % LAN_HASH_SIZE;
  1194. break;
  1195. }
  1196. #ifdef PF_INET6
  1197. case PF_INET6:
  1198. {
  1199. /* Use the lower 4 bytes of the IPV6 address. */
  1200. struct sockaddr_in6 *iaddr = (struct sockaddr_in6 *) addr;
  1201. idx = htonl(*((uint32_t *) &iaddr->sin6_addr.s6_addr[12]));
  1202. idx %= LAN_HASH_SIZE;
  1203. break;
  1204. }
  1205. #endif
  1206. default:
  1207. idx = 0;
  1208. }
  1209. idx %= LAN_HASH_SIZE;
  1210. return idx;
  1211. }
  1212. static void
  1213. lan_add_con(lan_data_t *lan)
  1214. {
  1215. unsigned int idx;
  1216. lan_link_t *head;
  1217. unsigned int i;
  1218. ipmi_lock(lan_list_lock);
  1219. idx = hash_lan(lan->ipmi);
  1220. head = &lan_list[idx];
  1221. lan->link.lan = lan;
  1222. lan->link.next = head;
  1223. lan->link.prev = head->prev;
  1224. head->prev->next = &lan->link;
  1225. head->prev = &lan->link;
  1226. for (i=0; i<lan->cparm.num_ip_addr; i++) {
  1227. struct sockaddr *addr = &lan->cparm.ip_addr[i].s_ipsock.s_addr;
  1228. idx = hash_lan_addr(addr);
  1229. head = &lan_ip_list[idx];
  1230. lan->ip[i].ip_link.lan = lan;
  1231. lan->ip[i].ip_link.next = head;
  1232. lan->ip[i].ip_link.prev = head->prev;
  1233. head->prev->next = &lan->ip[i].ip_link;
  1234. head->prev = &lan->ip[i].ip_link;
  1235. }
  1236. ipmi_unlock(lan_list_lock);
  1237. }
  1238. /* Must be called with the lan list lock held. */
  1239. static void
  1240. lan_remove_con_nolock(lan_data_t *lan)
  1241. {
  1242. unsigned int i;
  1243. if (!lan->link.lan)
  1244. /* Hasn't been initialized. */
  1245. return;
  1246. lan->link.prev->next = lan->link.next;
  1247. lan->link.next->prev = lan->link.prev;
  1248. lan->link.lan = NULL;
  1249. for (i=0; i<lan->cparm.num_ip_addr; i++) {
  1250. lan->ip[i].ip_link.prev->next = lan->ip[i].ip_link.next;
  1251. lan->ip[i].ip_link.next->prev = lan->ip[i].ip_link.prev;
  1252. lan->ip[i].ip_link.lan = NULL;
  1253. }
  1254. }
  1255. static lan_data_t *
  1256. lan_find_con(ipmi_con_t *ipmi)
  1257. {
  1258. unsigned int idx;
  1259. lan_link_t *l;
  1260. ipmi_lock(lan_list_lock);
  1261. idx = hash_lan(ipmi);
  1262. l = lan_list[idx].next;
  1263. while (l->lan) {
  1264. if (l->lan->ipmi == ipmi)
  1265. break;
  1266. l = l->next;
  1267. }
  1268. if (l->lan)
  1269. l->lan->refcount++;
  1270. ipmi_unlock(lan_list_lock);
  1271. return l->lan;
  1272. }
  1273. static inline int
  1274. cmp_timeval(struct timeval *tv1, struct timeval *tv2)
  1275. {
  1276. if (tv1->tv_sec < tv2->tv_sec)
  1277. return -1;
  1278. if (tv1->tv_sec > tv2->tv_sec)
  1279. return 1;
  1280. if (tv1->tv_usec < tv2->tv_usec)
  1281. return -1;
  1282. if (tv1->tv_usec > tv2->tv_usec)
  1283. return 1;
  1284. return 0;
  1285. }
  1286. typedef struct lan_add_stat_info_s
  1287. {
  1288. int statnum;
  1289. int count;
  1290. } lan_add_stat_info_t;
  1291. int
  1292. add_stat_cb(void *cb_data, void *item1, void *item2)
  1293. {
  1294. ipmi_ll_stat_info_t *info = item2;
  1295. lan_stat_info_t *stat = item1;
  1296. lan_add_stat_info_t *sinfo = cb_data;
  1297. if (stat->stats[sinfo->statnum])
  1298. ipmi_ll_con_stat_call_adder(info, stat->stats[sinfo->statnum],
  1299. sinfo->count);
  1300. return LOCKED_LIST_ITER_CONTINUE;
  1301. }
  1302. static inline void
  1303. add_stat(ipmi_con_t *ipmi, int stat, int count)
  1304. {
  1305. lan_data_t *lan = ipmi->con_data;
  1306. lan_add_stat_info_t sinfo;
  1307. sinfo.statnum = stat;
  1308. sinfo.count = count;
  1309. locked_list_iterate(lan->lan_stat_list, add_stat_cb, &sinfo);
  1310. }
  1311. static inline void
  1312. diff_timeval(struct timeval *dest,
  1313. struct timeval *left,
  1314. struct timeval *right)
  1315. {
  1316. if ( (left->tv_sec < right->tv_sec)
  1317. || ( (left->tv_sec == right->tv_sec)
  1318. && (left->tv_usec < right->tv_usec)))
  1319. {
  1320. /* If left < right, just force to zero, don't allow negative
  1321. numbers. */
  1322. dest->tv_sec = 0;
  1323. dest->tv_usec = 0;
  1324. return;
  1325. }
  1326. dest->tv_sec = left->tv_sec - right->tv_sec;
  1327. dest->tv_usec = left->tv_usec - right->tv_usec;
  1328. while (dest->tv_usec < 0) {
  1329. dest->tv_usec += 1000000;
  1330. dest->tv_sec--;
  1331. }
  1332. }
  1333. /* Must be called with the ipmi read or write lock. */
  1334. static int lan_valid_ipmi(ipmi_con_t *ipmi)
  1335. {
  1336. return (lan_find_con(ipmi) != NULL);
  1337. }
  1338. static void lan_cleanup(ipmi_con_t *ipmi);
  1339. static void
  1340. lan_put(ipmi_con_t *ipmi)
  1341. {
  1342. lan_data_t *lan = ipmi->con_data;
  1343. int done;
  1344. ipmi_lock(lan_list_lock);
  1345. lan->refcount--;
  1346. done = lan->refcount == 0;
  1347. /* If done, remove it before we release the lock. */
  1348. if (done)
  1349. lan_remove_con_nolock(lan);
  1350. ipmi_unlock(lan_list_lock);
  1351. if (done)
  1352. lan_cleanup(ipmi);
  1353. }
  1354. static int
  1355. auth_gen(lan_data_t *lan,
  1356. unsigned char *out,
  1357. uint8_t *ses_id,
  1358. uint8_t *seq,
  1359. unsigned char *data,
  1360. unsigned int data_len,
  1361. int addr_num)
  1362. {
  1363. int rv;
  1364. ipmi_auth_sg_t l[] =
  1365. { { ses_id, 4 },
  1366. { data, data_len },
  1367. { seq, 4 },
  1368. { NULL, 0 }};
  1369. rv = ipmi_auths[lan->ip[addr_num].working_authtype]
  1370. .authcode_gen(lan->authdata, l, out);
  1371. return rv;
  1372. }
  1373. static int
  1374. auth_check(lan_data_t *lan,
  1375. uint8_t *ses_id,
  1376. uint8_t *seq,
  1377. unsigned char *data,
  1378. unsigned int data_len,
  1379. unsigned char *code,
  1380. int addr_num)
  1381. {
  1382. int rv;
  1383. ipmi_auth_sg_t l[] =
  1384. { { ses_id, 4 },
  1385. { data, data_len },
  1386. { seq, 4 },
  1387. { NULL, 0 }};
  1388. rv = ipmi_auths[lan->ip[addr_num].working_authtype]
  1389. .authcode_check(lan->authdata, l, code);
  1390. return rv;
  1391. }
  1392. #define IPMI_MAX_LAN_LEN (IPMI_MAX_MSG_LENGTH + 128)
  1393. #define IPMI_LAN_MAX_HEADER 128
  1394. static int
  1395. rmcpp_format_msg(lan_data_t *lan, int addr_num,
  1396. unsigned int payload_type, int in_session,
  1397. unsigned char **msgdata, unsigned int *data_len,
  1398. unsigned int max_data_len, unsigned int header_len,
  1399. unsigned char *oem_iana, unsigned int oem_payload_id,
  1400. const ipmi_con_option_t *options)
  1401. {
  1402. unsigned char *tmsg;
  1403. int rv;
  1404. unsigned int header_used;
  1405. unsigned char *data;
  1406. unsigned int payload_len;
  1407. uint32_t *seqp;
  1408. int do_auth = 1;
  1409. int do_conf = 1;
  1410. if (options) {
  1411. while (options->option != IPMI_CON_OPTION_LIST_END) {
  1412. switch (options->option) {
  1413. case IPMI_CON_MSG_OPTION_AUTH:
  1414. do_auth = options->ival;
  1415. break;
  1416. case IPMI_CON_MSG_OPTION_CONF:
  1417. do_conf = options->ival;
  1418. break;
  1419. default:
  1420. /* Ignore unknown options. */
  1421. break;
  1422. }
  1423. options++;
  1424. }
  1425. }
  1426. do_conf = (do_conf && in_session
  1427. && (lan->ip[addr_num].working_conf
  1428. != IPMI_LANP_CONFIDENTIALITY_ALGORITHM_NONE));
  1429. do_auth = (do_auth && in_session
  1430. && (lan->ip[addr_num].working_integ
  1431. != IPMI_LANP_INTEGRITY_ALGORITHM_NONE));
  1432. if (do_conf) {
  1433. #if 0
  1434. if (! lan->ip[addr_num].working)
  1435. return EAGAIN;
  1436. #endif
  1437. /* Note: This may encrypt the data, the old data will be lost. */
  1438. rv = lan->ip[addr_num].conf_info->conf_encrypt
  1439. (lan->ipmi,
  1440. lan->ip[addr_num].conf_data,
  1441. msgdata,
  1442. &header_len, data_len,
  1443. &max_data_len);
  1444. if (rv)
  1445. return rv;
  1446. }
  1447. payload_len = *data_len;
  1448. if (payload_type == IPMI_RMCPP_PAYLOAD_TYPE_OEM_EXPLICIT)
  1449. header_used = 22;
  1450. else
  1451. header_used = 16;
  1452. if (header_used > header_len)
  1453. return E2BIG;
  1454. data = *msgdata - header_used;
  1455. *data_len += header_used;
  1456. max_data_len += header_used;
  1457. data[0] = 6; /* RMCP version 1.0. */
  1458. data[1] = 0;
  1459. data[2] = 0xff;
  1460. data[3] = 0x07;
  1461. data[4] = lan->ip[addr_num].working_authtype;
  1462. data[5] = payload_type;
  1463. tmsg = data+6;
  1464. if (payload_type == IPMI_RMCPP_PAYLOAD_TYPE_OEM_EXPLICIT) {
  1465. memcpy(tmsg, oem_iana, 3);
  1466. tmsg += 3;
  1467. *tmsg = 0;
  1468. tmsg++;
  1469. ipmi_set_uint16(tmsg, oem_payload_id);
  1470. tmsg += 2;
  1471. }
  1472. if (in_session) {
  1473. if (do_conf)
  1474. data[5] |= 0x80;
  1475. if (do_auth) {
  1476. seqp = &(lan->ip[addr_num].outbound_seq_num);
  1477. data[5] |= 0x40;
  1478. } else {
  1479. seqp = &(lan->ip[addr_num].unauth_out_seq_num);
  1480. }
  1481. ipmi_set_uint32(tmsg, lan->ip[addr_num].mgsys_session_id);
  1482. tmsg += 4;
  1483. ipmi_set_uint32(tmsg, *seqp);
  1484. tmsg += 4;
  1485. } else {
  1486. ipmi_set_uint32(tmsg, 0); /* session id */
  1487. tmsg += 4;
  1488. ipmi_set_uint32(tmsg, 0); /* session sequence number */
  1489. tmsg += 4;
  1490. seqp = NULL;
  1491. }
  1492. /* Payload length doesn't include the padding. */
  1493. ipmi_set_uint16(tmsg, payload_len);
  1494. if (do_auth) {
  1495. rv = lan->ip[addr_num].integ_info->integ_pad
  1496. (lan->ipmi,
  1497. lan->ip[addr_num].integ_data,
  1498. data, data_len,
  1499. max_data_len);
  1500. if (rv)
  1501. return rv;
  1502. rv = lan->ip[addr_num].integ_info->integ_add
  1503. (lan->ipmi,
  1504. lan->ip[addr_num].integ_data,
  1505. data, data_len,
  1506. max_data_len);
  1507. if (rv)
  1508. return rv;
  1509. }
  1510. if (seqp) {
  1511. (*seqp)++;
  1512. if (*seqp == 0)
  1513. *seqp = 1;
  1514. }
  1515. *msgdata = data;
  1516. return 0;
  1517. }
  1518. static int
  1519. lan15_format_msg(lan_data_t *lan, int addr_num,
  1520. unsigned char **msgdata, unsigned int *data_len)
  1521. {
  1522. unsigned char *data;
  1523. int rv;
  1524. if (lan->ip[addr_num].working_authtype == IPMI_AUTHTYPE_NONE)
  1525. data = *msgdata - 14;
  1526. else
  1527. data = *msgdata - 30;
  1528. data[0] = 6; /* RMCP version 1.0. */
  1529. data[1] = 0;
  1530. data[2] = 0xff;
  1531. data[3] = 0x07;
  1532. data[4] = lan->ip[addr_num].working_authtype;
  1533. ipmi_set_uint32(data+5, lan->ip[addr_num].outbound_seq_num);
  1534. ipmi_set_uint32(data+9, lan->ip[addr_num].session_id);
  1535. /* FIXME - need locks for the sequence numbers. */
  1536. /* Increment the outbound number, but make sure it's not zero. If
  1537. it's already zero, ignore it, we are in pre-setup. */
  1538. if (lan->ip[addr_num].outbound_seq_num != 0) {
  1539. (lan->ip[addr_num].outbound_seq_num)++;
  1540. if (lan->ip[addr_num].outbound_seq_num == 0)
  1541. (lan->ip[addr_num].outbound_seq_num)++;
  1542. }
  1543. if (lan->ip[addr_num].working_authtype == IPMI_AUTHTYPE_NONE) {
  1544. /* No authentication, so no authcode. */
  1545. data[13] = *data_len;
  1546. *data_len += 14;
  1547. } else {
  1548. data[29] = *data_len;
  1549. rv = auth_gen(lan, data+13, data+9, data+5, *msgdata, *data_len,
  1550. addr_num);
  1551. if (rv)
  1552. return rv;
  1553. *data_len += 30;
  1554. }
  1555. *msgdata = data;
  1556. return 0;
  1557. }
  1558. static int
  1559. lan_send_addr(lan_data_t *lan,
  1560. const ipmi_addr_t *addr,
  1561. int addr_len,
  1562. const ipmi_msg_t *msg,
  1563. uint8_t seq,
  1564. int addr_num,
  1565. const ipmi_con_option_t *options)
  1566. {
  1567. unsigned char data[IPMI_MAX_LAN_LEN+IPMI_LAN_MAX_HEADER];
  1568. unsigned char *tmsg;
  1569. unsigned int pos;
  1570. int rv;
  1571. unsigned int payload_type;
  1572. int out_of_session = 0;
  1573. ipmi_payload_t *payload = NULL;
  1574. unsigned char oem_iana[3] = {0, 0, 0};
  1575. unsigned int oem_payload_id = 0;
  1576. if ((addr->addr_type >= IPMI_RMCPP_ADDR_START)
  1577. && (addr->addr_type <= IPMI_RMCPP_ADDR_END))
  1578. {
  1579. /*
  1580. * Let through the dodgy IPMI 1.5 Serial-over-LAN packets, but block
  1581. * anything else that tries to send an RMCP+ packet to a non-RMCP+
  1582. * host.
  1583. */
  1584. if ((addr->addr_type != IPMI_RMCPP_ADDR_SOL)
  1585. && (lan->ip[addr_num].working_authtype != IPMI_AUTHTYPE_RMCP_PLUS))
  1586. return EINVAL;
  1587. payload_type = addr->addr_type - IPMI_RMCPP_ADDR_START;
  1588. } else {
  1589. switch (addr->addr_type) {
  1590. case IPMI_SYSTEM_INTERFACE_ADDR_TYPE:
  1591. case IPMI_IPMB_ADDR_TYPE:
  1592. case IPMI_IPMB_BROADCAST_ADDR_TYPE:
  1593. payload_type = IPMI_RMCPP_PAYLOAD_TYPE_IPMI;
  1594. break;
  1595. default:
  1596. return EINVAL;
  1597. }
  1598. }
  1599. if ((payload_type == IPMI_RMCPP_PAYLOAD_TYPE_OEM_EXPLICIT)
  1600. || ((payload_type >= 0x20) && (payload_type <= 0x27)))
  1601. {
  1602. ipmi_rmcpp_addr_t *addr = (ipmi_rmcpp_addr_t *) addr;
  1603. payload_entry_t *e;
  1604. if (payload_type == IPMI_RMCPP_PAYLOAD_TYPE_OEM_EXPLICIT) {
  1605. memcpy(oem_iana, addr->oem_iana, 3);
  1606. oem_payload_id = addr->oem_payload_id;
  1607. } else {
  1608. memcpy(oem_iana, lan->oem_iana, 3);
  1609. oem_payload_id = 0;
  1610. }
  1611. /* No lock required, only payload additions are allowed. */
  1612. e = oem_payload_list;
  1613. while (e) {
  1614. if ((e->payload_type == payload_type)
  1615. && (memcmp(e->iana, oem_iana, 3) == 0)
  1616. && (e->payload_id == oem_payload_id))
  1617. {
  1618. payload = e->payload;
  1619. break;
  1620. }
  1621. e = e->next;
  1622. }
  1623. } else {
  1624. payload = payloads[payload_type];
  1625. }
  1626. tmsg = data + IPMI_LAN_MAX_HEADER;
  1627. if (!payload) {
  1628. return ENOSYS;
  1629. } else {
  1630. pos = IPMI_MAX_LAN_LEN;
  1631. rv = payload->format_for_xmit(lan->ipmi, addr, addr_len,
  1632. msg, tmsg, &pos,
  1633. &out_of_session, seq);
  1634. if (rv)
  1635. return rv;
  1636. }
  1637. if (lan->ip[addr_num].working_authtype == IPMI_AUTHTYPE_RMCP_PLUS) {
  1638. rv = rmcpp_format_msg(lan, addr_num,
  1639. payload_type, !out_of_session,
  1640. &tmsg, &pos,
  1641. IPMI_MAX_LAN_LEN, IPMI_LAN_MAX_HEADER,
  1642. oem_iana, oem_payload_id, options);
  1643. } else {
  1644. rv = lan15_format_msg(lan, addr_num, &tmsg, &pos);
  1645. if (addr->addr_type == IPMI_RMCPP_ADDR_SOL)
  1646. /*
  1647. * We're sending SoL over IPMI 1.5, which requires that we set
  1648. * a "reserved" bit. This is dodgy.
  1649. */
  1650. tmsg[4] |= 0x80;
  1651. }
  1652. if (rv)
  1653. return rv;
  1654. if (DEBUG_RAWMSG) {
  1655. char buf1[32], buf2[32];
  1656. ipmi_log(IPMI_LOG_DEBUG_START, "%soutgoing seq %d\n addr =",
  1657. IPMI_CONN_NAME(lan->ipmi), seq);
  1658. dump_hex((unsigned char *) &(lan->cparm.ip_addr[addr_num]),
  1659. sizeof(sockaddr_ip_t));
  1660. ipmi_log(IPMI_LOG_DEBUG_CONT,
  1661. "\n msg = netfn=%s cmd=%s data_len=%d.",
  1662. ipmi_get_netfn_string(msg->netfn, buf1, 32),
  1663. ipmi_get_command_string(msg->netfn, msg->cmd, buf2, 32),
  1664. msg->data_len);
  1665. if (pos) {
  1666. ipmi_log(IPMI_LOG_DEBUG_CONT, "\n data =\n ");
  1667. dump_hex(tmsg, pos);
  1668. }
  1669. ipmi_log(IPMI_LOG_DEBUG_END, " ");
  1670. }
  1671. add_stat(lan->ipmi, STAT_XMIT_PACKETS, 1);
  1672. rv = sendto(lan->fd->fd, tmsg, pos, 0,
  1673. (struct sockaddr *) &(lan->cparm.ip_addr[addr_num].s_ipsock),
  1674. lan->cparm.ip_addr[addr_num].ip_addr_len);
  1675. if (rv == -1)
  1676. rv = errno;
  1677. else
  1678. rv = 0;
  1679. return rv;
  1680. }
  1681. static int
  1682. lan_send(lan_data_t *lan,
  1683. const ipmi_addr_t *addr,
  1684. int addr_len,
  1685. const ipmi_msg_t *msg,
  1686. uint8_t seq,
  1687. int *send_ip_num,
  1688. const ipmi_con_option_t *options)
  1689. {
  1690. int curr_ip_addr;
  1691. ipmi_lock(lan->ip_lock);
  1692. if (msg->netfn & 1) {
  1693. /* For unacknowledged packets, don't switch addresses. They
  1694. don't contribute to detecting that the link is down. */
  1695. curr_ip_addr = lan->curr_ip_addr;
  1696. } else if (lan->connected) {
  1697. lan->num_sends++;
  1698. /* We periodically switch between IP addresses, just to make sure
  1699. they are all operational. */
  1700. if ((lan->num_sends % SENDS_BETWEEN_IP_SWITCHES) == 0) {
  1701. unsigned int addr_num = lan->curr_ip_addr + 1;
  1702. if (addr_num >= lan->cparm.num_ip_addr)
  1703. addr_num = 0;
  1704. while (addr_num != lan->curr_ip_addr) {
  1705. if (lan->ip[addr_num].working)
  1706. break;
  1707. addr_num++;
  1708. if (addr_num >= lan->cparm.num_ip_addr)
  1709. addr_num = 0;
  1710. }
  1711. lan->curr_ip_addr = addr_num;
  1712. }
  1713. } else {
  1714. /* Just rotate between IP addresses if we are not yet connected */
  1715. unsigned int addr_num = lan->curr_ip_addr + 1;
  1716. if (addr_num >= lan->cparm.num_ip_addr)
  1717. addr_num = 0;
  1718. lan->curr_ip_addr = addr_num;
  1719. }
  1720. curr_ip_addr = lan->curr_ip_addr;
  1721. ipmi_unlock(lan->ip_lock);
  1722. *send_ip_num = curr_ip_addr;
  1723. return lan_send_addr(lan, addr, addr_len, msg, seq, curr_ip_addr, options);
  1724. }
  1725. typedef struct call_ipmb_change_handler_s
  1726. {
  1727. lan_data_t *lan;
  1728. int err;
  1729. const unsigned char *ipmb_addr;
  1730. unsigned int num_ipmb_addr;
  1731. int active;
  1732. unsigned int hacks;
  1733. } call_ipmb_change_handler_t;
  1734. static int
  1735. call_ipmb_change_handler(void *cb_data, void *item1, void *item2)
  1736. {
  1737. call_ipmb_change_handler_t *info = cb_data;
  1738. ipmi_ll_ipmb_addr_cb handler = item1;
  1739. handler(info->lan->ipmi, info->err, info->ipmb_addr, info->num_ipmb_addr,
  1740. info->active, info->hacks, item2);
  1741. return LOCKED_LIST_ITER_CONTINUE;
  1742. }
  1743. static void
  1744. call_ipmb_change_handlers(lan_data_t *lan, int err,
  1745. const unsigned char ipmb_addr[],
  1746. unsigned int num_ipmb_addr,
  1747. int active, unsigned int hacks)
  1748. {
  1749. call_ipmb_change_handler_t info;
  1750. info.lan = lan;
  1751. info.err = err;
  1752. info.ipmb_addr = ipmb_addr;
  1753. info.num_ipmb_addr = num_ipmb_addr;
  1754. info.active = active;
  1755. info.hacks = hacks;
  1756. locked_list_iterate(lan->ipmb_change_handlers, call_ipmb_change_handler,
  1757. &info);
  1758. }
  1759. static int
  1760. lan_add_ipmb_addr_handler(ipmi_con_t *ipmi,
  1761. ipmi_ll_ipmb_addr_cb handler,
  1762. void *cb_data)
  1763. {
  1764. lan_data_t *lan = (lan_data_t *) ipmi->con_data;
  1765. if (locked_list_add(lan->ipmb_change_handlers, handler, cb_data))
  1766. return 0;
  1767. else
  1768. return ENOMEM;
  1769. }
  1770. static int
  1771. lan_remove_ipmb_addr_handler(ipmi_con_t *ipmi,
  1772. ipmi_ll_ipmb_addr_cb handler,
  1773. void *cb_data)
  1774. {
  1775. lan_data_t *lan = (lan_data_t *) ipmi->con_data;
  1776. if (locked_list_remove(lan->ipmb_change_handlers, handler, cb_data))
  1777. return 0;
  1778. else
  1779. return EINVAL;
  1780. }
  1781. static void
  1782. ipmb_handler(ipmi_con_t *ipmi,
  1783. int err,
  1784. const unsigned char ipmb_addr[],
  1785. unsigned int num_ipmb_addr,
  1786. int active,
  1787. unsigned int hacks,
  1788. void *cb_data)
  1789. {
  1790. lan_data_t *lan;
  1791. int changed = 0;
  1792. int i;
  1793. if (err)
  1794. return;
  1795. lan = (lan_data_t *) ipmi->con_data;
  1796. for (i=0; i<MAX_IPMI_USED_CHANNELS; i++) {
  1797. if (! ipmb_addr[i])
  1798. continue;
  1799. if (ipmb_addr[i] != lan->slave_addr[i]) {
  1800. lan->slave_addr[i] = ipmb_addr[i];
  1801. ipmi->ipmb_addr[i] = ipmb_addr[i];
  1802. changed = 1;
  1803. }
  1804. }
  1805. if (changed || (lan->is_active != active)) {
  1806. lan->is_active = active;
  1807. ipmi->hacks = hacks;
  1808. call_ipmb_change_handlers(lan, err, ipmb_addr, num_ipmb_addr,
  1809. active, hacks);
  1810. }
  1811. }
  1812. static void
  1813. audit_timeout_handler(void *cb_data,
  1814. os_hnd_timer_id_t *id)
  1815. {
  1816. audit_timer_info_t *info = cb_data;
  1817. ipmi_con_t *ipmi = info->ipmi;
  1818. lan_data_t *lan;
  1819. struct timeval timeout;
  1820. ipmi_msg_t msg;
  1821. unsigned int i;
  1822. ipmi_system_interface_addr_t si;
  1823. int start_up[MAX_IP_ADDR];
  1824. /* If we were cancelled, just free the data and ignore the call. */
  1825. if (info->cancelled)
  1826. goto out_done;
  1827. if (!lan_valid_ipmi(ipmi))
  1828. goto out_done;
  1829. lan = ipmi->con_data;
  1830. /* Send message to all addresses we think are down. If the
  1831. connection is down, this will bring it up, otherwise it
  1832. will keep it alive. */
  1833. ipmi_lock(lan->ip_lock);
  1834. for (i=0; i<lan->cparm.num_ip_addr; i++)
  1835. start_up[i] = ! lan->ip[i].working;
  1836. ipmi_unlock(lan->ip_lock);
  1837. for (i=0; i<lan->cparm.num_ip_addr; i++) {
  1838. if (start_up[i])
  1839. send_auth_cap(ipmi, lan, i, 0);
  1840. }
  1841. msg.netfn = IPMI_APP_NETFN;
  1842. msg.cmd = IPMI_GET_DEVICE_ID_CMD;
  1843. msg.data = NULL;
  1844. msg.data_len = 0;
  1845. /* Send a message to check the working of the interface. */
  1846. if (ipmi->get_ipmb_addr) {
  1847. /* If we have a way to query the IPMB address, do so
  1848. periodically. */
  1849. ipmi->get_ipmb_addr(ipmi, ipmb_handler, NULL);
  1850. } else {
  1851. si.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
  1852. si.channel = 0xf;
  1853. si.lun = 0;
  1854. ipmi->send_command(ipmi, (ipmi_addr_t *) &si, sizeof(si),
  1855. &msg, NULL, NULL);
  1856. }
  1857. timeout.tv_sec = LAN_AUDIT_TIMEOUT / 1000000;
  1858. timeout.tv_usec = LAN_AUDIT_TIMEOUT % 1000000;
  1859. ipmi->os_hnd->start_timer(ipmi->os_hnd,
  1860. id,
  1861. &timeout,
  1862. audit_timeout_handler,
  1863. cb_data);
  1864. /* Make sure the timer info doesn't get freed. */
  1865. info = NULL;
  1866. lan_put(ipmi);
  1867. out_done:
  1868. if (info) {
  1869. ipmi->os_hnd->free_timer(ipmi->os_hnd, id);
  1870. ipmi_mem_free(info);
  1871. }
  1872. return;
  1873. }
  1874. typedef struct call_con_change_handler_s
  1875. {
  1876. lan_data_t *lan;
  1877. int err;
  1878. unsigned int port;
  1879. int any_port_up;
  1880. } call_con_change_handler_t;
  1881. static int
  1882. call_con_change_handler(void *cb_data, void *item1, void *item2)
  1883. {
  1884. call_con_change_handler_t *info = cb_data;
  1885. ipmi_ll_con_changed_cb handler = item1;
  1886. handler(info->lan->ipmi, info->err, info->port, info->any_port_up, item2);
  1887. return LOCKED_LIST_ITER_CONTINUE;
  1888. }
  1889. static void
  1890. call_con_change_handlers(lan_data_t *lan, int err, unsigned int port,
  1891. int any_port_up)
  1892. {
  1893. call_con_change_handler_t info;
  1894. info.lan = lan;
  1895. info.err = err;
  1896. info.port = port;
  1897. info.any_port_up = any_port_up;
  1898. locked_list_iterate(lan->con_change_handlers, call_con_change_handler,
  1899. &info);
  1900. }
  1901. void
  1902. _ipmi_lan_con_change_lock(ipmi_con_t *ipmi)
  1903. {
  1904. lan_data_t *lan = (lan_data_t *) ipmi->con_data;
  1905. ipmi_lock(lan->ip_lock);
  1906. ipmi_lock(lan->con_change_lock);
  1907. ipmi_unlock(lan->ip_lock);
  1908. }
  1909. void
  1910. _ipmi_lan_con_change_unlock(ipmi_con_t *ipmi)
  1911. {
  1912. lan_data_t *lan = (lan_data_t *) ipmi->con_data;
  1913. ipmi_unlock(lan->con_change_lock);
  1914. }
  1915. void
  1916. _ipmi_lan_call_con_change_handlers(ipmi_con_t *ipmi,
  1917. int err,
  1918. unsigned int port)
  1919. {
  1920. lan_data_t *lan = (lan_data_t *) ipmi->con_data;
  1921. call_con_change_handlers(lan, err, port, lan->connected);
  1922. }
  1923. static int
  1924. lan_add_con_change_handler(ipmi_con_t *ipmi,
  1925. ipmi_ll_con_changed_cb handler,
  1926. void *cb_data)
  1927. {
  1928. lan_data_t *lan = (lan_data_t *) ipmi->con_data;
  1929. if (locked_list_add(lan->con_change_handlers, handler, cb_data))
  1930. return 0;
  1931. else
  1932. return ENOMEM;
  1933. }
  1934. static int
  1935. lan_remove_con_change_handler(ipmi_con_t *ipmi,
  1936. ipmi_ll_con_changed_cb handler,
  1937. void *cb_data)
  1938. {
  1939. lan_data_t *lan = (lan_data_t *) ipmi->con_data;
  1940. if (locked_list_remove(lan->con_change_handlers, handler, cb_data))
  1941. return 0;
  1942. else
  1943. return EINVAL;
  1944. }
  1945. static void
  1946. connection_up(lan_data_t *lan, int addr_num, int new_con)
  1947. {
  1948. add_stat(lan->ipmi, STAT_CONN_UP, 1);
  1949. ipmi_lock(lan->ip_lock);
  1950. if ((! lan->ip[addr_num].working) && new_con) {
  1951. lan->ip[addr_num].working = 1;
  1952. ipmi_log(IPMI_LOG_INFO,
  1953. "%sipmi_lan.c(connection_up): "
  1954. "Connection %d to the BMC is up",
  1955. IPMI_CONN_NAME(lan->ipmi), addr_num);
  1956. }
  1957. if (new_con) {
  1958. ipmi_log(IPMI_LOG_INFO,
  1959. "%sipmi_lan.c(connection_up): "
  1960. "Connection to the BMC restored",
  1961. IPMI_CONN_NAME(lan->ipmi));
  1962. lan->curr_ip_addr = addr_num;
  1963. }
  1964. if (lan->connected) {
  1965. ipmi_lock(lan->con_change_lock);
  1966. ipmi_unlock(lan->ip_lock);
  1967. call_con_change_handlers(lan, 0, addr_num, 1);
  1968. ipmi_unlock(lan->con_change_lock);
  1969. } else {
  1970. ipmi_unlock(lan->ip_lock);
  1971. }
  1972. }
  1973. static void
  1974. reset_session_data(lan_data_t *lan, int addr_num)
  1975. {
  1976. lan_ip_data_t *ip = &lan->ip[addr_num];
  1977. ip->outbound_seq_num = 0;
  1978. ip->inbound_seq_num = 0;
  1979. ip->session_id = 0;
  1980. ip->mgsys_session_id = 0;
  1981. ip->precon_session_id = 0;
  1982. ip->precon_mgsys_session_id = 0;
  1983. ip->recv_msg_map = 0;
  1984. ip->unauth_recv_msg_map = 0;
  1985. ip->working_authtype = 0;
  1986. ip->unauth_out_seq_num = 0;
  1987. ip->unauth_in_seq_num = 0;
  1988. if (ip->conf_data) {
  1989. ip->conf_info->conf_free(lan->ipmi, ip->conf_data);
  1990. ip->conf_data = NULL;
  1991. }
  1992. ip->conf_info = NULL;
  1993. if (ip->integ_data) {
  1994. ip->integ_info->integ_free(lan->ipmi, ip->integ_data);
  1995. ip->integ_data = NULL;
  1996. }
  1997. ip->integ_info = NULL;
  1998. ip->working_conf = IPMI_LANP_CONFIDENTIALITY_ALGORITHM_NONE;
  1999. ip->working_integ = IPMI_LANP_INTEGRITY_ALGORITHM_NONE;
  2000. }
  2001. static void
  2002. lost_connection(lan_data_t *lan, unsigned int addr_num)
  2003. {
  2004. unsigned int i;
  2005. ipmi_lock(lan->ip_lock);
  2006. if (! lan->ip[addr_num].working) {
  2007. ipmi_unlock(lan->ip_lock);
  2008. return;
  2009. }
  2010. add_stat(lan->ipmi, STAT_CONN_DOWN, 1);
  2011. lan->ip[addr_num].working = 0;
  2012. reset_session_data(lan, addr_num);
  2013. ipmi_log(IPMI_LOG_WARNING,
  2014. "%sipmi_lan.c(lost_connection): "
  2015. "Connection %d to the BMC is down",
  2016. IPMI_CONN_NAME(lan->ipmi), addr_num);
  2017. if (lan->curr_ip_addr == addr_num) {
  2018. /* Scan to see if any address is operational. */
  2019. for (i=0; i<lan->cparm.num_ip_addr; i++) {
  2020. if (lan->ip[i].working) {
  2021. lan->curr_ip_addr = i;
  2022. break;
  2023. }
  2024. }
  2025. if (i >= lan->cparm.num_ip_addr) {
  2026. /* There were no operational connections, report that. */
  2027. ipmi_log(IPMI_LOG_SEVERE,
  2028. "%sipmi_lan.c(lost_connection): "
  2029. "All connections to the BMC are down",
  2030. IPMI_CONN_NAME(lan->ipmi));
  2031. lan->connected = 0;
  2032. }
  2033. }
  2034. {
  2035. int connected = lan->connected;
  2036. ipmi_lock(lan->con_change_lock);
  2037. ipmi_unlock(lan->ip_lock);
  2038. call_con_change_handlers(lan, ETIMEDOUT, addr_num, connected);
  2039. ipmi_unlock(lan->con_change_lock);
  2040. }
  2041. }
  2042. static void
  2043. rsp_timeout_handler(void *cb_data,
  2044. os_hnd_timer_id_t *id)
  2045. {
  2046. lan_timer_info_t *info = cb_data;
  2047. ipmi_con_t *ipmi = info->ipmi;
  2048. lan_data_t *lan;
  2049. int seq;
  2050. ipmi_ll_rsp_handler_t handler;
  2051. ipmi_msgi_t *rspi;
  2052. int ip_num = 0;
  2053. int call_lost_con = 0;
  2054. if (!lan_valid_ipmi(ipmi))
  2055. return;
  2056. lan = ipmi->con_data;
  2057. seq = info->seq;
  2058. ipmi_lock(lan->seq_num_lock);
  2059. /* If we were cancelled, just free the data and ignore it. */
  2060. if (info->cancelled) {
  2061. ipmi_unlock(lan->seq_num_lock);
  2062. goto out;
  2063. }
  2064. if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
  2065. ipmi_log(IPMI_LOG_DEBUG, "%sTimeout for seq #%d",
  2066. IPMI_CONN_NAME(ipmi), seq);
  2067. if (! lan->seq_table[seq].inuse) {
  2068. ipmi_unlock(lan->seq_num_lock);
  2069. goto out;
  2070. }
  2071. if (DEBUG_RAWMSG) {
  2072. ip_num = lan->seq_table[seq].last_ip_num;
  2073. ipmi_log(IPMI_LOG_DEBUG,
  2074. "%sSeq #%d\n"
  2075. " addr_type=%d, ip_num=%d, fails=%d\n"
  2076. " fail_start_time=%ld.%6.6ld",
  2077. IPMI_CONN_NAME(ipmi),
  2078. seq, lan->seq_table[seq].addr.addr_type,
  2079. lan->seq_table[seq].last_ip_num,
  2080. lan->ip[ip_num].consecutive_failures,
  2081. lan->ip[ip_num].failure_time.tv_sec,
  2082. lan->ip[ip_num].failure_time.tv_usec);
  2083. }
  2084. if (lan->seq_table[seq].addr.addr_type == IPMI_SYSTEM_INTERFACE_ADDR_TYPE)
  2085. {
  2086. /* We only count timeouts on messages to the system interface.
  2087. Otherwise, if we sent a bunch of messages to the IPMB that
  2088. timed out, we might trigger this code accidentally. */
  2089. ip_num = lan->seq_table[seq].last_ip_num;
  2090. ipmi_lock(lan->ip_lock);
  2091. if (lan->ip[ip_num].working) {
  2092. if (lan->ip[ip_num].consecutive_failures == 0) {
  2093. /* Set the time when the connection will be considered
  2094. failed. */
  2095. gettimeofday(&(lan->ip[ip_num].failure_time), NULL);
  2096. lan->ip[ip_num].failure_time.tv_sec += IP_FAIL_TIME / 1000000;
  2097. lan->ip[ip_num].failure_time.tv_usec += IP_FAIL_TIME % 1000000;
  2098. if (lan->ip[ip_num].failure_time.tv_usec > 1000000) {
  2099. lan->ip[ip_num].failure_time.tv_sec += 1;
  2100. lan->ip[ip_num].failure_time.tv_usec -= 1000000;
  2101. }
  2102. lan->ip[ip_num].consecutive_failures = 1;
  2103. ipmi_unlock(lan->ip_lock);
  2104. } else if (!lan->seq_table[seq].side_effects) {
  2105. /* Don't use messages with side effects for failure
  2106. detection. */
  2107. lan->ip[ip_num].consecutive_failures++;
  2108. if (lan->ip[ip_num].consecutive_failures >= IP_FAIL_COUNT) {
  2109. struct timeval now;
  2110. ipmi_unlock(lan->ip_lock);
  2111. gettimeofday(&now, NULL);
  2112. if (cmp_timeval(&now, &lan->ip[ip_num].failure_time) > 0)
  2113. {
  2114. /* Can't report yet, still holding locks. */
  2115. call_lost_con = 1;
  2116. }
  2117. } else {
  2118. ipmi_unlock(lan->ip_lock);
  2119. }
  2120. }
  2121. } else {
  2122. ipmi_unlock(lan->ip_lock);
  2123. }
  2124. }
  2125. rspi = lan->seq_table[seq].rsp_item;
  2126. if (lan->seq_table[seq].retries_left > 0)
  2127. {
  2128. struct timeval timeout;
  2129. int rv;
  2130. lan->seq_table[seq].retries_left--;
  2131. add_stat(ipmi, STAT_REXMITS, 1);
  2132. /* Note that we will need a new session seq # here, we can't reuse
  2133. the old one. If the message got lost on the way back, the other
  2134. end would silently ignore resends of the seq #. */
  2135. if (lan->seq_table[seq].addr_num >= 0)
  2136. rv = lan_send_addr(lan,
  2137. &(lan->seq_table[seq].addr),
  2138. lan->seq_table[seq].addr_len,
  2139. &(lan->seq_table[seq].msg),
  2140. seq,
  2141. lan->seq_table[seq].addr_num,
  2142. NULL);
  2143. else
  2144. rv = lan_send(lan,
  2145. &(lan->seq_table[seq].addr),
  2146. lan->seq_table[seq].addr_len,
  2147. &(lan->seq_table[seq].msg),
  2148. seq,
  2149. &(lan->seq_table[seq].last_ip_num),
  2150. NULL);
  2151. if (rv) {
  2152. /* If we get an error resending the message, report an unknown
  2153. error. */
  2154. rspi->data[0] = IPMI_UNKNOWN_ERR_CC;
  2155. } else {
  2156. if (!lan->seq_table[seq].side_effects) {
  2157. timeout.tv_sec = LAN_RSP_TIMEOUT / 1000000;
  2158. timeout.tv_usec = LAN_RSP_TIMEOUT % 1000000;
  2159. } else {
  2160. timeout.tv_sec = LAN_RSP_TIMEOUT_SIDEEFF / 1000000;
  2161. timeout.tv_usec = LAN_RSP_TIMEOUT_SIDEEFF % 1000000;
  2162. }
  2163. ipmi->os_hnd->start_timer(ipmi->os_hnd,
  2164. id,
  2165. &timeout,
  2166. rsp_timeout_handler,
  2167. cb_data);
  2168. ipmi_unlock(lan->seq_num_lock);
  2169. if (call_lost_con)
  2170. lost_connection(lan, ip_num);
  2171. lan_put(ipmi);
  2172. return;
  2173. }
  2174. } else {
  2175. add_stat(ipmi, STAT_TIMED_OUT, 1);
  2176. rspi->data[0] = IPMI_TIMEOUT_CC;
  2177. }
  2178. rspi->msg.netfn = lan->seq_table[seq].msg.netfn | 1;
  2179. rspi->msg.cmd = lan->seq_table[seq].msg.cmd;
  2180. rspi->msg.data = rspi->data;
  2181. rspi->msg.data_len = 1;
  2182. if (lan->seq_table[seq].use_orig_addr) {
  2183. /* We did an address translation, so translate back. */
  2184. memcpy(&rspi->addr, &lan->seq_table[seq].orig_addr,
  2185. lan->seq_table[seq].orig_addr_len);
  2186. rspi->addr_len = lan->seq_table[seq].orig_addr_len;
  2187. } else {
  2188. memcpy(&rspi->addr,
  2189. &(lan->seq_table[seq].addr),
  2190. lan->seq_table[seq].addr_len);
  2191. rspi->addr_len = lan->seq_table[seq].addr_len;
  2192. }
  2193. handler = lan->seq_table[seq].rsp_handler;
  2194. lan->seq_table[seq].inuse = 0;
  2195. check_command_queue(ipmi, lan);
  2196. ipmi_unlock(lan->seq_num_lock);
  2197. ipmi->os_hnd->free_timer(ipmi->os_hnd, id);
  2198. /* Convert broadcasts back into normal sends. */
  2199. if (rspi->addr.addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE)
  2200. rspi->addr.addr_type = IPMI_IPMB_ADDR_TYPE;
  2201. if (call_lost_con)
  2202. lost_connection(lan, ip_num);
  2203. ipmi_handle_rsp_item(ipmi, rspi, handler);
  2204. out:
  2205. lan_put(ipmi);
  2206. ipmi_mem_free(info);
  2207. }
  2208. typedef struct call_event_handler_s
  2209. {
  2210. lan_data_t *lan;
  2211. const ipmi_addr_t *addr;
  2212. unsigned int addr_len;
  2213. ipmi_event_t *event;
  2214. } call_event_handler_t;
  2215. static int
  2216. call_event_handler(void *cb_data, void *item1, void *item2)
  2217. {
  2218. call_event_handler_t *info = cb_data;
  2219. ipmi_ll_evt_handler_t handler = item1;
  2220. handler(info->lan->ipmi, info->addr, info->addr_len, info->event, item2);
  2221. return LOCKED_LIST_ITER_CONTINUE;
  2222. }
  2223. static int
  2224. lan_add_event_handler(ipmi_con_t *ipmi,
  2225. ipmi_ll_evt_handler_t handler,
  2226. void *cb_data)
  2227. {
  2228. lan_data_t *lan = (lan_data_t *) ipmi->con_data;
  2229. if (locked_list_add(lan->event_handlers, handler, cb_data))
  2230. return 0;
  2231. else
  2232. return ENOMEM;
  2233. }
  2234. static int
  2235. lan_remove_event_handler(ipmi_con_t *ipmi,
  2236. ipmi_ll_evt_handler_t handler,
  2237. void *cb_data)
  2238. {
  2239. lan_data_t *lan = (lan_data_t *) ipmi->con_data;
  2240. if (locked_list_remove(lan->event_handlers, handler, cb_data))
  2241. return 0;
  2242. else
  2243. return EINVAL;
  2244. }
  2245. static ipmi_mcid_t invalid_mcid = IPMI_MCID_INVALID;
  2246. static void
  2247. handle_async_event(ipmi_con_t *ipmi,
  2248. const ipmi_addr_t *addr,
  2249. unsigned int addr_len,
  2250. const ipmi_msg_t *msg)
  2251. {
  2252. lan_data_t *lan = (lan_data_t *) ipmi->con_data;
  2253. ipmi_event_t *event = NULL;
  2254. ipmi_time_t timestamp;
  2255. call_event_handler_t info;
  2256. add_stat(ipmi, STAT_ASYNC_EVENTS, 1);
  2257. if (msg) {
  2258. unsigned int type = msg->data[2];
  2259. unsigned int record_id = ipmi_get_uint16(msg->data);
  2260. if (type < 0xe0)
  2261. timestamp = ipmi_seconds_to_time(ipmi_get_uint32(msg->data+3));
  2262. else
  2263. timestamp = -1;
  2264. event = ipmi_event_alloc(invalid_mcid,
  2265. record_id,
  2266. type,
  2267. timestamp,
  2268. msg->data+3, 13);
  2269. if (!event)
  2270. /* We missed it here, but the SEL fetch should catch it later. */
  2271. return;
  2272. }
  2273. info.lan = lan;
  2274. info.addr = addr;
  2275. info.addr_len = addr_len;
  2276. info.event = event;
  2277. locked_list_iterate(lan->event_handlers, call_event_handler, &info);
  2278. if (event)
  2279. ipmi_event_free(event);
  2280. }
  2281. /* Must be called with the message sequence lock held. */
  2282. static int
  2283. handle_msg_send(lan_timer_info_t *info,
  2284. int addr_num,
  2285. const ipmi_addr_t *addr,
  2286. unsigned int addr_len,
  2287. const ipmi_msg_t *msg,
  2288. ipmi_ll_rsp_handler_t rsp_handler,
  2289. ipmi_msgi_t *rspi,
  2290. int side_effects)
  2291. {
  2292. ipmi_con_t *ipmi = info->ipmi;
  2293. lan_data_t *lan = ipmi->con_data;
  2294. unsigned int seq;
  2295. struct timeval timeout;
  2296. int rv;
  2297. ipmi_addr_t tmp_addr;
  2298. const ipmi_addr_t *orig_addr = NULL;
  2299. unsigned int orig_addr_len = 0;
  2300. seq = (lan->last_seq + 1) % 64;
  2301. if (seq == 0)
  2302. seq++;
  2303. while (lan->seq_table[seq].inuse) {
  2304. if (seq == lan->last_seq) {
  2305. /* This cannot really happen if max_outstanding_msg_count <= 63. */
  2306. ipmi_log(IPMI_LOG_FATAL,
  2307. "%sipmi_lan.c(handle_msg_send): "
  2308. "ipmi_lan: Attempted to start too many messages",
  2309. IPMI_CONN_NAME(ipmi));
  2310. abort();
  2311. }
  2312. seq = (seq + 1) % 64;
  2313. if (seq == 0)
  2314. seq++;
  2315. }
  2316. if (DEBUG_MSG) {
  2317. char buf1[32], buf2[32];
  2318. ipmi_log(IPMI_LOG_DEBUG_START, "%soutgoing msg to IPMI addr =",
  2319. IPMI_CONN_NAME(ipmi));
  2320. dump_hex((unsigned char *) addr, addr_len);
  2321. ipmi_log(IPMI_LOG_DEBUG_CONT,
  2322. "\n msg = netfn=%s cmd=%s data_len=%d",
  2323. ipmi_get_netfn_string(msg->netfn, buf1, 32),
  2324. ipmi_get_command_string(msg->netfn, msg->cmd, buf2, 32),
  2325. msg->data_len);
  2326. if (msg->data_len) {
  2327. ipmi_log(IPMI_LOG_DEBUG_CONT, "\n data(len=%d.) =\n ",
  2328. msg->data_len);
  2329. dump_hex(msg->data, msg->data_len);
  2330. }
  2331. ipmi_log(IPMI_LOG_DEBUG_END, " ");
  2332. }
  2333. if ((addr->addr_type == IPMI_IPMB_ADDR_TYPE)
  2334. || (addr->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE))
  2335. {
  2336. ipmi_ipmb_addr_t *ipmb = (ipmi_ipmb_addr_t *) addr;
  2337. if (ipmb->channel >= MAX_IPMI_USED_CHANNELS) {
  2338. ipmi->os_hnd->free_timer(ipmi->os_hnd, info->timer);
  2339. ipmi_mem_free(info);
  2340. rv = EINVAL;
  2341. goto out;
  2342. }
  2343. if (ipmb->slave_addr == lan->slave_addr[ipmb->channel]) {
  2344. ipmi_system_interface_addr_t *si = (void *) &tmp_addr;
  2345. /* Most systems don't handle sending to your own slave
  2346. address, so we have to translate here. */
  2347. si->addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
  2348. si->channel = IPMI_BMC_CHANNEL;
  2349. si->lun = ipmb->lun;
  2350. orig_addr = addr;
  2351. orig_addr_len = addr_len;
  2352. addr = &tmp_addr;
  2353. addr_len = sizeof(*si);
  2354. }
  2355. }
  2356. info->seq = seq;
  2357. lan->seq_table[seq].inuse = 1;
  2358. lan->seq_table[seq].side_effects = side_effects;
  2359. lan->seq_table[seq].addr_num = addr_num;
  2360. lan->seq_table[seq].rsp_handler = rsp_handler;
  2361. lan->seq_table[seq].rsp_item = rspi;
  2362. memcpy(&(lan->seq_table[seq].addr), addr, addr_len);
  2363. lan->seq_table[seq].addr_len = addr_len;
  2364. lan->seq_table[seq].msg = *msg;
  2365. lan->seq_table[seq].msg.data = lan->seq_table[seq].data;
  2366. memcpy(lan->seq_table[seq].data, msg->data, msg->data_len);
  2367. lan->seq_table[seq].timer_info = info;
  2368. if (addr->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE)
  2369. lan->seq_table[seq].retries_left = 0;
  2370. else
  2371. lan->seq_table[seq].retries_left = LAN_RSP_RETRIES;
  2372. if (orig_addr) {
  2373. lan->seq_table[seq].use_orig_addr = 1;
  2374. memcpy(&(lan->seq_table[seq].orig_addr), orig_addr, orig_addr_len);
  2375. lan->seq_table[seq].orig_addr_len = orig_addr_len;
  2376. /* In case it's a broadcast. */
  2377. lan->seq_table[seq].orig_addr.addr_type = IPMI_IPMB_ADDR_TYPE;
  2378. } else {
  2379. lan->seq_table[seq].use_orig_addr = 0;
  2380. }
  2381. if (!side_effects) {
  2382. timeout.tv_sec = LAN_RSP_TIMEOUT / 1000000;
  2383. timeout.tv_usec = LAN_RSP_TIMEOUT % 1000000;
  2384. } else {
  2385. timeout.tv_sec = LAN_RSP_TIMEOUT_SIDEEFF / 1000000;
  2386. timeout.tv_usec = LAN_RSP_TIMEOUT_SIDEEFF % 1000000;
  2387. }
  2388. lan->seq_table[seq].timer = info->timer;
  2389. rv = ipmi->os_hnd->start_timer(ipmi->os_hnd,
  2390. lan->seq_table[seq].timer,
  2391. &timeout,
  2392. rsp_timeout_handler,
  2393. info);
  2394. if (rv) {
  2395. lan->seq_table[seq].inuse = 0;
  2396. ipmi->os_hnd->free_timer(ipmi->os_hnd,
  2397. lan->seq_table[seq].timer);
  2398. lan->seq_table[seq].timer = NULL;
  2399. ipmi_mem_free(info);
  2400. goto out;
  2401. }
  2402. lan->last_seq = seq;
  2403. if (addr_num >= 0) {
  2404. rv = lan_send_addr(lan, addr, addr_len, msg, seq, addr_num, NULL);
  2405. lan->seq_table[seq].last_ip_num = addr_num;
  2406. } else {
  2407. rv = lan_send(lan, addr, addr_len, msg, seq,
  2408. &(lan->seq_table[seq].last_ip_num),
  2409. NULL);
  2410. }
  2411. if (rv) {
  2412. int err;
  2413. lan->seq_table[seq].inuse = 0;
  2414. err = ipmi->os_hnd->stop_timer(ipmi->os_hnd,
  2415. lan->seq_table[seq].timer);
  2416. /* Special handling, if we can't remove the timer, then it
  2417. will time out on us, so we need to not free the command and
  2418. instead let the timeout handle freeing it. */
  2419. if (err) {
  2420. info->cancelled = 1;
  2421. } else {
  2422. ipmi->os_hnd->free_timer(ipmi->os_hnd,
  2423. lan->seq_table[seq].timer);
  2424. lan->seq_table[seq].timer = NULL;
  2425. ipmi_mem_free(info);
  2426. }
  2427. }
  2428. out:
  2429. return rv;
  2430. }
  2431. static void
  2432. check_command_queue(ipmi_con_t *ipmi, lan_data_t *lan)
  2433. {
  2434. int rv;
  2435. lan_wait_queue_t *q_item;
  2436. int started = 0;
  2437. while (!started && (lan->wait_q != NULL)) {
  2438. /* Commands are waiting to be started, remove the queue item
  2439. and start it. */
  2440. q_item = lan->wait_q;
  2441. lan->wait_q = q_item->next;
  2442. if (lan->wait_q == NULL)
  2443. lan->wait_q_tail = NULL;
  2444. rv = handle_msg_send(q_item->info, -1, &q_item->addr, q_item->addr_len,
  2445. &(q_item->msg), q_item->rsp_handler,
  2446. q_item->rsp_item, q_item->side_effects);
  2447. if (rv) {
  2448. ipmi_unlock(lan->seq_num_lock);
  2449. /* Send an error response to the user. */
  2450. ipmi_log(IPMI_LOG_ERR_INFO,
  2451. "%sipmi_lan.c(check_command_queue): "
  2452. "Command was not able to be sent due to error 0x%x",
  2453. IPMI_CONN_NAME(ipmi), rv);
  2454. q_item->msg.netfn |= 1; /* Convert it to a response. */
  2455. q_item->msg.data[0] = IPMI_UNKNOWN_ERR_CC;
  2456. q_item->msg.data_len = 1;
  2457. q_item->info = NULL;
  2458. ipmi_handle_rsp_item_copyall(ipmi, q_item->rsp_item,
  2459. &q_item->addr, q_item->addr_len,
  2460. &q_item->msg, q_item->rsp_handler);
  2461. ipmi_lock(lan->seq_num_lock);
  2462. } else {
  2463. /* We successfully sent a message, break out of the loop. */
  2464. started = 1;
  2465. }
  2466. ipmi_mem_free(q_item);
  2467. }
  2468. if (!started)
  2469. lan->outstanding_msg_count--;
  2470. }
  2471. /* Per the spec, RMCP and RMCP+ have different allowed sequence number
  2472. ranges, so adjust for this. */
  2473. static int
  2474. check_session_seq_num(lan_data_t *lan, uint32_t seq,
  2475. uint32_t *in_seq, uint16_t *map,
  2476. int gt_allowed, int lt_allowed)
  2477. {
  2478. /* Check the sequence number. */
  2479. if ((int) (seq - *in_seq) <= gt_allowed) {
  2480. /* It's after the current sequence number, but within 8. We
  2481. move the sequence number forward. */
  2482. *map <<= seq - *in_seq;
  2483. *map |= 1;
  2484. *in_seq = seq;
  2485. } else if ((int) (*in_seq - seq) <= lt_allowed) {
  2486. /* It's before the current sequence number, but within 8. */
  2487. uint8_t bit = 1 << (*in_seq - seq);
  2488. if (*map & bit) {
  2489. /* We've already received the message, so discard it. */
  2490. add_stat(lan->ipmi, STAT_DUPLICATES, 1);
  2491. if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
  2492. ipmi_log(IPMI_LOG_DEBUG, "%sDropped message duplicate",
  2493. IPMI_CONN_NAME(lan->ipmi));
  2494. return EINVAL;
  2495. }
  2496. *map |= bit;
  2497. } else {
  2498. /* It's outside the current sequence number range, discard
  2499. the packet. */
  2500. add_stat(lan->ipmi, STAT_SEQ_OUT_OF_RANGE, 1);
  2501. if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
  2502. ipmi_log(IPMI_LOG_DEBUG, "%sDropped message out of seq range",
  2503. IPMI_CONN_NAME(lan->ipmi));
  2504. return EINVAL;
  2505. }
  2506. return 0;
  2507. }
  2508. static int
  2509. check_15_session_seq_num(lan_data_t *lan, uint32_t seq,
  2510. uint32_t *in_seq, uint16_t *map)
  2511. {
  2512. return check_session_seq_num(lan, seq, in_seq, map, 8, 8);
  2513. }
  2514. static int
  2515. check_20_session_seq_num(lan_data_t *lan, uint32_t seq,
  2516. uint32_t *in_seq, uint16_t *map)
  2517. {
  2518. return check_session_seq_num(lan, seq, in_seq, map, 15, 16);
  2519. }
  2520. static void
  2521. handle_payload(ipmi_con_t *ipmi,
  2522. lan_data_t *lan,
  2523. int addr_num,
  2524. int payload_type,
  2525. unsigned char *tmsg,
  2526. unsigned int payload_len)
  2527. {
  2528. ipmi_ll_rsp_handler_t handler;
  2529. ipmi_msgi_t *rspi;
  2530. unsigned char seq;
  2531. int rv;
  2532. int (*handle_send_rsp)(ipmi_con_t *con, ipmi_msg_t *msg);
  2533. handle_send_rsp = NULL;
  2534. if (payload_type == IPMI_RMCPP_PAYLOAD_TYPE_OPEN_SESSION_RESPONSE) {
  2535. if (payload_len < 1) {
  2536. add_stat(ipmi, STAT_TOO_SHORT, 1);
  2537. if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
  2538. ipmi_log(IPMI_LOG_DEBUG, "%sPayload length to short",
  2539. IPMI_CONN_NAME(ipmi));
  2540. goto out;
  2541. }
  2542. /* We use the message tag field to store the sequence #. */
  2543. seq = tmsg[0] & 0x3f;
  2544. } else if (payload_type == IPMI_RMCPP_PAYLOAD_TYPE_OEM_EXPLICIT) {
  2545. #if 0
  2546. /* FIXME - add handling of OEM payloads. */
  2547. handle_oem_payload(ipmi, lan, oem_iana, oem_payload_id,
  2548. tmsg, payload_len);
  2549. #else
  2550. goto out;
  2551. #endif
  2552. } else if (! payloads[payload_type]) {
  2553. add_stat(ipmi, STAT_INVALID_PAYLOAD, 1);
  2554. if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
  2555. ipmi_log(IPMI_LOG_DEBUG, "%sUnhandled payload: 0x%x",
  2556. IPMI_CONN_NAME(ipmi), payload_type);
  2557. goto out;
  2558. } else {
  2559. rv = payloads[payload_type]->get_recv_seq(ipmi, tmsg,
  2560. payload_len, &seq);
  2561. if (rv == ENOSYS) {
  2562. payloads[payload_type]->handle_recv_async(ipmi, tmsg, payload_len);
  2563. goto out;
  2564. } else if (rv) {
  2565. add_stat(ipmi, STAT_SEQ_ERR, 1);
  2566. if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
  2567. ipmi_log(IPMI_LOG_DEBUG, "%sError getting sequence: 0x%x",
  2568. IPMI_CONN_NAME(ipmi), rv);
  2569. goto out;
  2570. }
  2571. }
  2572. ipmi_lock(lan->seq_num_lock);
  2573. if (! lan->seq_table[seq].inuse) {
  2574. add_stat(ipmi, STAT_RSP_NO_CMD, 1);
  2575. if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
  2576. ipmi_log(IPMI_LOG_DEBUG,
  2577. "%sDropped message seq not in use: 0x%x",
  2578. IPMI_CONN_NAME(ipmi), seq);
  2579. goto out_unlock;
  2580. }
  2581. rv = payloads[payload_type]->handle_recv_rsp
  2582. (ipmi,
  2583. lan->seq_table[seq].rsp_item,
  2584. &lan->seq_table[seq].addr,
  2585. lan->seq_table[seq].addr_len,
  2586. &lan->seq_table[seq].msg,
  2587. tmsg,
  2588. payload_len);
  2589. if (rv) {
  2590. if (rv == -1)
  2591. handle_send_rsp = ipmi->handle_send_rsp_err;
  2592. else
  2593. goto out_unlock;
  2594. }
  2595. /* We got a response from the connection, so reset the failure
  2596. count. */
  2597. lan->ip[addr_num].consecutive_failures = 0;
  2598. /* The command matches up, cancel the timer and deliver it */
  2599. rv = ipmi->os_hnd->stop_timer(ipmi->os_hnd,
  2600. lan->seq_table[seq].timer);
  2601. if (rv)
  2602. /* Couldn't cancel the timer, make sure the timer
  2603. doesn't do the callback. */
  2604. lan->seq_table[seq].timer_info->cancelled = 1;
  2605. else {
  2606. /* Timer is cancelled, free its data. */
  2607. ipmi->os_hnd->free_timer(ipmi->os_hnd,
  2608. lan->seq_table[seq].timer);
  2609. ipmi_mem_free(lan->seq_table[seq].timer_info);
  2610. }
  2611. handler = lan->seq_table[seq].rsp_handler;
  2612. rspi = lan->seq_table[seq].rsp_item;
  2613. lan->seq_table[seq].inuse = 0;
  2614. if (lan->seq_table[seq].use_orig_addr) {
  2615. /* We did an address translation, so translate back. */
  2616. memcpy(&rspi->addr, &lan->seq_table[seq].orig_addr,
  2617. lan->seq_table[seq].orig_addr_len);
  2618. rspi->addr_len = lan->seq_table[seq].orig_addr_len;
  2619. }
  2620. check_command_queue(ipmi, lan);
  2621. ipmi_unlock(lan->seq_num_lock);
  2622. if (handle_send_rsp)
  2623. handle_send_rsp(ipmi, &rspi->msg);
  2624. ipmi_handle_rsp_item(ipmi, rspi, handler);
  2625. out:
  2626. return;
  2627. out_unlock:
  2628. ipmi_unlock(lan->seq_num_lock);
  2629. }
  2630. static void
  2631. handle_rmcpp_recv(ipmi_con_t *ipmi,
  2632. lan_data_t *lan,
  2633. int addr_num,
  2634. unsigned char *data,
  2635. unsigned int len)
  2636. {
  2637. unsigned char oem_iana[3] = { 0, 0, 0 };
  2638. unsigned int oem_payload_id = 0;
  2639. unsigned char *tmsg;
  2640. int encrypted;
  2641. int authenticated;
  2642. unsigned int payload_type;
  2643. uint32_t session_id;
  2644. uint32_t session_seq;
  2645. int rv;
  2646. unsigned int payload_len;
  2647. unsigned int header_len;
  2648. if (len < 16) { /* Minimum size of an RMCP+ msg. */
  2649. if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
  2650. ipmi_log(IPMI_LOG_DEBUG,
  2651. "%sDropped message because too small(5)",
  2652. IPMI_CONN_NAME(ipmi));
  2653. goto out;
  2654. }
  2655. encrypted = data[5] & 0x80;
  2656. authenticated = data[5] & 0x40;
  2657. payload_type = data[5] & 0x3f;
  2658. tmsg = data+6;
  2659. if (payload_type == IPMI_RMCPP_PAYLOAD_TYPE_OEM_EXPLICIT) {
  2660. if (len < 22) { /* Minimum size of an RMCP+ type 2 msg. */
  2661. if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
  2662. ipmi_log(IPMI_LOG_DEBUG,
  2663. "%sDropped message because too small(6)",
  2664. IPMI_CONN_NAME(ipmi));
  2665. goto out;
  2666. }
  2667. memcpy(oem_iana, tmsg, 3);
  2668. tmsg += 4;
  2669. oem_payload_id = ipmi_get_uint16(tmsg);
  2670. tmsg += 2;
  2671. }
  2672. session_id = ipmi_get_uint32(tmsg);
  2673. tmsg += 4;
  2674. if (session_id != lan->ip[addr_num].session_id) {
  2675. add_stat(ipmi, STAT_BAD_SESSION_ID, 1);
  2676. if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
  2677. ipmi_log(IPMI_LOG_DEBUG,
  2678. "%sDropped message not valid session id (2)",
  2679. IPMI_CONN_NAME(ipmi));
  2680. goto out;
  2681. }
  2682. session_seq = ipmi_get_uint32(tmsg);
  2683. tmsg += 4;
  2684. payload_len = ipmi_get_uint16(tmsg);
  2685. tmsg += 2;
  2686. header_len = tmsg - data;
  2687. if ((header_len + payload_len) > len) {
  2688. add_stat(ipmi, STAT_BAD_SIZE, 1);
  2689. if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
  2690. ipmi_log(IPMI_LOG_DEBUG,
  2691. "%sDropped message payload length doesn't match up",
  2692. IPMI_CONN_NAME(ipmi));
  2693. goto out;
  2694. }
  2695. /* Authenticate the message before we do anything else. */
  2696. if (authenticated) {
  2697. unsigned int pad_len;
  2698. unsigned int integ_len;
  2699. if (lan->ip[addr_num].working_integ
  2700. == IPMI_LANP_INTEGRITY_ALGORITHM_NONE)
  2701. {
  2702. add_stat(ipmi, STAT_INVALID_AUTH, 1);
  2703. if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
  2704. ipmi_log(IPMI_LOG_DEBUG,
  2705. "%sGot authenticated msg but authentication"
  2706. " not available", IPMI_CONN_NAME(ipmi));
  2707. goto out;
  2708. }
  2709. /* Increase the length to include the padding; this eases the
  2710. handling for the payload integrity check. */
  2711. integ_len = header_len + payload_len;
  2712. while ((integ_len < len) && (data[integ_len] == 0xff))
  2713. integ_len++;
  2714. if (integ_len < len)
  2715. integ_len++;
  2716. rv = lan->ip[addr_num].integ_info->integ_check
  2717. (ipmi,
  2718. lan->ip[addr_num].integ_data,
  2719. data,
  2720. integ_len,
  2721. len);
  2722. if (rv) {
  2723. add_stat(ipmi, STAT_AUTH_FAIL, 1);
  2724. if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
  2725. ipmi_log(IPMI_LOG_DEBUG, "%sIntegrity failed",
  2726. IPMI_CONN_NAME(ipmi));
  2727. goto out;
  2728. }
  2729. /* Remove the integrity padding. */
  2730. pad_len = data[integ_len-1] + 1;
  2731. if ((integ_len - header_len - pad_len) != payload_len) {
  2732. add_stat(ipmi, STAT_BAD_SIZE, 1);
  2733. if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
  2734. ipmi_log(IPMI_LOG_DEBUG, "%sPadding size not valid: %d",
  2735. IPMI_CONN_NAME(ipmi), pad_len);
  2736. goto out;
  2737. }
  2738. }
  2739. /* The packet is good, we can trust the data in it now. */
  2740. /* If it's from a down connection, report it as up. */
  2741. ipmi_lock(lan->ip_lock);
  2742. if (! lan->ip[addr_num].working) {
  2743. ipmi_unlock(lan->ip_lock);
  2744. connection_up(lan, addr_num, 0);
  2745. ipmi_lock(lan->ip_lock);
  2746. }
  2747. if (authenticated)
  2748. rv = check_20_session_seq_num(lan, session_seq,
  2749. &(lan->ip[addr_num].inbound_seq_num),
  2750. &(lan->ip[addr_num].recv_msg_map));
  2751. else if (session_id == 0)
  2752. rv = 0; /* seq num not used for out-of-session messages. */
  2753. else
  2754. rv = check_20_session_seq_num(lan, session_seq,
  2755. &(lan->ip[addr_num].unauth_in_seq_num),
  2756. &(lan->ip[addr_num].unauth_recv_msg_map));
  2757. ipmi_unlock(lan->ip_lock);
  2758. if (rv) {
  2759. if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
  2760. ipmi_log(IPMI_LOG_DEBUG, "%sInvalid sequence number",
  2761. IPMI_CONN_NAME(ipmi));
  2762. add_stat(ipmi, STAT_SEQ_OUT_OF_RANGE, 1);
  2763. goto out;
  2764. }
  2765. /* Message is in sequence, so it's good to deliver after we
  2766. decrypt it. */
  2767. if (encrypted) {
  2768. if (lan->ip[addr_num].working_conf
  2769. == IPMI_LANP_CONFIDENTIALITY_ALGORITHM_NONE)
  2770. {
  2771. add_stat(ipmi, STAT_INVALID_AUTH, 1);
  2772. if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
  2773. ipmi_log(IPMI_LOG_DEBUG,
  2774. "%sGot encrypted msg but encryption not available",
  2775. IPMI_CONN_NAME(ipmi));
  2776. goto out;
  2777. }
  2778. rv = lan->ip[addr_num].conf_info->conf_decrypt
  2779. (ipmi, lan->ip[addr_num].conf_data, &tmsg, &payload_len);
  2780. if (rv) {
  2781. add_stat(ipmi, STAT_DECRYPT_FAIL, 1);
  2782. if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
  2783. ipmi_log(IPMI_LOG_DEBUG, "%sDecryption failed",
  2784. IPMI_CONN_NAME(ipmi));
  2785. goto out;
  2786. }
  2787. }
  2788. handle_payload(ipmi, lan, addr_num, payload_type, tmsg, payload_len);
  2789. out:
  2790. return;
  2791. }
  2792. static void
  2793. handle_lan15_recv(ipmi_con_t *ipmi,
  2794. lan_data_t *lan,
  2795. int addr_num,
  2796. unsigned char *data,
  2797. unsigned int len)
  2798. {
  2799. uint32_t seq, sess_id;
  2800. unsigned char *tmsg = NULL;
  2801. unsigned int data_len;
  2802. int rv;
  2803. if ((data[4] & 0x0f) == IPMI_AUTHTYPE_NONE) {
  2804. if (len < 14) { /* Minimum size of an IPMI msg. */
  2805. add_stat(ipmi, STAT_TOO_SHORT, 1);
  2806. if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
  2807. ipmi_log(IPMI_LOG_DEBUG,
  2808. "%sDropped message because too small(1)",
  2809. IPMI_CONN_NAME(ipmi));
  2810. goto out;
  2811. }
  2812. /* No authentication. */
  2813. if (len < (unsigned int) (data[13] + 14)) {
  2814. /* Not enough data was supplied, reject the message. */
  2815. add_stat(ipmi, STAT_TOO_SHORT, 1);
  2816. if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
  2817. ipmi_log(IPMI_LOG_DEBUG,
  2818. "%sDropped message because too small(2)",
  2819. IPMI_CONN_NAME(ipmi));
  2820. goto out;
  2821. }
  2822. data_len = data[13];
  2823. } else {
  2824. if (len < 30) { /* Minimum size of an authenticated IPMI msg. */
  2825. add_stat(ipmi, STAT_TOO_SHORT, 1);
  2826. if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
  2827. ipmi_log(IPMI_LOG_DEBUG,
  2828. "%sDropped message because too small(3)",
  2829. IPMI_CONN_NAME(ipmi));
  2830. goto out;
  2831. }
  2832. /* authcode in message, add 16 to the above checks. */
  2833. if (len < (unsigned int) (data[29] + 30)) {
  2834. add_stat(ipmi, STAT_TOO_SHORT, 1);
  2835. /* Not enough data was supplied, reject the message. */
  2836. if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
  2837. ipmi_log(IPMI_LOG_DEBUG,
  2838. "%sDropped message because too small(4)",
  2839. IPMI_CONN_NAME(ipmi));
  2840. goto out;
  2841. }
  2842. data_len = data[29];
  2843. }
  2844. /* FIXME - need a lock on the session data. */
  2845. /* Drop if the authtypes are incompatible. */
  2846. if (lan->ip[addr_num].working_authtype != (data[4] & 0x0f)) {
  2847. add_stat(ipmi, STAT_INVALID_AUTH, 1);
  2848. if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
  2849. ipmi_log(IPMI_LOG_DEBUG, "%sDropped message not valid authtype,"
  2850. " expected %d, got %d",
  2851. IPMI_CONN_NAME(ipmi),
  2852. lan->ip[addr_num].working_authtype,
  2853. data[4] & 0x0f);
  2854. goto out;
  2855. }
  2856. /* Drop if sessions ID's don't match. */
  2857. sess_id = ipmi_get_uint32(data+9);
  2858. if (sess_id != lan->ip[addr_num].session_id) {
  2859. add_stat(ipmi, STAT_BAD_SESSION_ID, 1);
  2860. if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
  2861. ipmi_log(IPMI_LOG_DEBUG,
  2862. "%sDropped message not valid session id",
  2863. IPMI_CONN_NAME(ipmi));
  2864. goto out;
  2865. }
  2866. seq = ipmi_get_uint32(data+5);
  2867. if ((data[4] & 0x0f) != 0) {
  2868. /* Validate the message's authcode. Do this before checking
  2869. the session seq num so we know the data is valid. */
  2870. rv = auth_check(lan, data+9, data+5, data+30, data[29], data+13,
  2871. addr_num);
  2872. if (rv) {
  2873. add_stat(ipmi, STAT_AUTH_FAIL, 1);
  2874. if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
  2875. ipmi_log(IPMI_LOG_DEBUG, "%sDropped message auth fail",
  2876. IPMI_CONN_NAME(ipmi));
  2877. goto out;
  2878. }
  2879. tmsg = data + 30;
  2880. } else {
  2881. tmsg = data + 14;
  2882. }
  2883. /* If it's from a down connection, report it as up. */
  2884. ipmi_lock(lan->ip_lock);
  2885. if (! lan->ip[addr_num].working) {
  2886. ipmi_unlock(lan->ip_lock);
  2887. connection_up(lan, addr_num, 0);
  2888. ipmi_lock(lan->ip_lock);
  2889. }
  2890. rv = check_15_session_seq_num(lan, seq,
  2891. &(lan->ip[addr_num].inbound_seq_num),
  2892. &(lan->ip[addr_num].recv_msg_map));
  2893. ipmi_unlock(lan->ip_lock);
  2894. if (rv)
  2895. goto out;
  2896. /*
  2897. * Special case for Serial-over-LAN IPMI 1.5 packets, which use the
  2898. * "reserved" nybble to identify the SoL payload.
  2899. */
  2900. if ((data[4] & 0xf0) == 0x80)
  2901. handle_payload(ipmi, lan, addr_num,
  2902. IPMI_RMCPP_PAYLOAD_TYPE_SOL, tmsg, data_len);
  2903. else
  2904. handle_payload(ipmi, lan, addr_num,
  2905. IPMI_RMCPP_PAYLOAD_TYPE_IPMI, tmsg, data_len);
  2906. out:
  2907. return;
  2908. }
  2909. static int
  2910. addr_match_lan(lan_data_t *lan, uint32_t sid, sockaddr_ip_t *addr,
  2911. int *raddr_num)
  2912. {
  2913. unsigned int addr_num;
  2914. /* Make sure the source address matches one we expect from
  2915. this system. */
  2916. for (addr_num = 0; addr_num < lan->cparm.num_ip_addr; addr_num++) {
  2917. if ((!sid || (lan->ip[addr_num].session_id == sid))
  2918. && lan_addr_same(&(lan->cparm.ip_addr[addr_num]), addr))
  2919. {
  2920. *raddr_num = addr_num;
  2921. return 1;
  2922. }
  2923. }
  2924. return 0;
  2925. }
  2926. static ipmi_con_t *
  2927. rmcpp_find_ipmi(lan_fd_t *item,
  2928. unsigned char *data,
  2929. unsigned int len,
  2930. sockaddr_ip_t *addr,
  2931. int *addr_num)
  2932. {
  2933. /* This is easy, the session id is our slot in the fd or is a
  2934. message tag. */
  2935. unsigned char payload;
  2936. uint32_t tag;
  2937. uint32_t sid;
  2938. unsigned char ctag;
  2939. unsigned int mlen;
  2940. unsigned char *d;
  2941. ipmi_con_t *ipmi = NULL;
  2942. lan_data_t *lan;
  2943. /* We need to find the sessions id; it's position depends on
  2944. the payload type. */
  2945. if (len < 16) {
  2946. if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
  2947. ipmi_log(IPMI_LOG_DEBUG, "Message too short(2): %d", len);
  2948. return NULL;
  2949. }
  2950. payload = data[5] & 0x3f;
  2951. if (payload == IPMI_RMCPP_PAYLOAD_TYPE_OEM_EXPLICIT) {
  2952. if (len < 22) {
  2953. if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
  2954. ipmi_log(IPMI_LOG_DEBUG, "Message too short(3): %d", len);
  2955. return NULL;
  2956. }
  2957. d = data+12;
  2958. } else {
  2959. d = data+6;
  2960. }
  2961. mlen = ipmi_get_uint16(d+8);
  2962. if ((mlen + 10 + (d-data)) > len) {
  2963. if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
  2964. ipmi_log(IPMI_LOG_DEBUG,
  2965. "Dropped message payload length doesn't match up");
  2966. return NULL;
  2967. }
  2968. sid = ipmi_get_uint32(d);
  2969. if ((sid == 0) && payloads[payload]->get_msg_tag) {
  2970. int rv = payloads[payload]->get_msg_tag(d+10, mlen, &ctag);
  2971. if (rv) {
  2972. if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
  2973. ipmi_log(IPMI_LOG_DEBUG, "Error getting message tag: %d", rv);
  2974. return NULL;
  2975. }
  2976. tag = ctag;
  2977. } else
  2978. tag = sid - 1;
  2979. if (tag >= MAX_CONS_PER_FD) {
  2980. if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
  2981. ipmi_log(IPMI_LOG_DEBUG, "tag is out of range: %d", tag);
  2982. return NULL;
  2983. }
  2984. ipmi_lock(item->con_lock);
  2985. lan = item->lan[tag];
  2986. if (lan && addr_match_lan(lan, sid, addr, addr_num))
  2987. ipmi = lan->ipmi;
  2988. else if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
  2989. ipmi_log(IPMI_LOG_DEBUG, "tag doesn't match: %d", tag);
  2990. ipmi_unlock(item->con_lock);
  2991. return ipmi;
  2992. }
  2993. static ipmi_con_t *
  2994. rmcp_find_ipmi(lan_fd_t *item,
  2995. unsigned char *data,
  2996. unsigned int len,
  2997. sockaddr_ip_t *addr,
  2998. int *addr_num)
  2999. {
  3000. /* Old RMCP is harder, we have to hunt. */
  3001. uint32_t sid;
  3002. lan_data_t *lan;
  3003. int i;
  3004. ipmi_con_t *ipmi = NULL;
  3005. if (len < 13) {
  3006. if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
  3007. ipmi_log(IPMI_LOG_DEBUG, "Message too short(4): %d", len);
  3008. return NULL;
  3009. }
  3010. sid = ipmi_get_uint32(data+9);
  3011. ipmi_lock(item->con_lock);
  3012. for (i=0; i<MAX_CONS_PER_FD; i++) {
  3013. lan = item->lan[i];
  3014. if (lan && addr_match_lan(lan, sid, addr, addr_num)) {
  3015. ipmi = lan->ipmi;
  3016. break;
  3017. }
  3018. }
  3019. ipmi_unlock(item->con_lock);
  3020. return ipmi;
  3021. }
  3022. static void
  3023. data_handler(int fd,
  3024. void *cb_data,
  3025. os_hnd_fd_id_t *id)
  3026. {
  3027. lan_fd_t *item = cb_data;
  3028. ipmi_con_t *ipmi;
  3029. lan_data_t *lan;
  3030. unsigned char data[IPMI_MAX_LAN_LEN];
  3031. sockaddr_ip_t ipaddrd;
  3032. socklen_t from_len;
  3033. int len;
  3034. int addr_num = 0; /* Keep gcc happy and initialize */
  3035. from_len = sizeof(ipaddrd.s_ipsock);
  3036. len = recvfrom(fd, data, sizeof(data), 0, (struct sockaddr *)&ipaddrd,
  3037. &from_len);
  3038. if (len < 0)
  3039. /* Got an error, probably no data, just return. */
  3040. return;
  3041. ipaddrd.ip_addr_len = from_len;
  3042. if (DEBUG_RAWMSG) {
  3043. ipmi_log(IPMI_LOG_DEBUG_START, "incoming\n addr = ");
  3044. dump_hex((unsigned char *) &ipaddrd, from_len);
  3045. if (len) {
  3046. ipmi_log(IPMI_LOG_DEBUG_CONT, "\n data =\n ");
  3047. dump_hex(data, len);
  3048. }
  3049. ipmi_log(IPMI_LOG_DEBUG_END, " ");
  3050. }
  3051. if (len < 5) {
  3052. if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
  3053. ipmi_log(IPMI_LOG_DEBUG, "Message too short(1): %d", len);
  3054. return;
  3055. }
  3056. /* Validate the RMCP portion of the message. */
  3057. if ((data[0] != 6)
  3058. || (data[2] != 0xff)
  3059. || (data[3] != 0x07))
  3060. {
  3061. if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
  3062. ipmi_log(IPMI_LOG_DEBUG, "Dropped message not valid IPMI/RMCP");
  3063. return;
  3064. }
  3065. if ((data[4] & 0x0f) == IPMI_AUTHTYPE_RMCP_PLUS) {
  3066. ipmi = rmcpp_find_ipmi(item, data, len, &ipaddrd, &addr_num);
  3067. } else {
  3068. ipmi = rmcp_find_ipmi(item, data, len, &ipaddrd, &addr_num);
  3069. }
  3070. if (!lan_valid_ipmi(ipmi))
  3071. /* This can fail due to a race condition, just return and
  3072. everything should be fine. */
  3073. return;
  3074. lan = ipmi->con_data;
  3075. add_stat(ipmi, STAT_RECV_PACKETS, 1);
  3076. if ((data[4] & 0x0f) == IPMI_AUTHTYPE_RMCP_PLUS) {
  3077. handle_rmcpp_recv(ipmi, lan, addr_num, data, len);
  3078. } else {
  3079. handle_lan15_recv(ipmi, lan, addr_num, data, len);
  3080. }
  3081. lan_put(ipmi);
  3082. return;
  3083. }
  3084. /* Note that this puts the address number in data4 of the rspi. */
  3085. int
  3086. ipmi_lan_send_command_forceip(ipmi_con_t *ipmi,
  3087. int addr_num,
  3088. ipmi_addr_t *addr,
  3089. unsigned int addr_len,
  3090. ipmi_msg_t *msg,
  3091. ipmi_ll_rsp_handler_t rsp_handler,
  3092. ipmi_msgi_t *rspi)
  3093. {
  3094. lan_timer_info_t *info;
  3095. lan_data_t *lan;
  3096. int rv;
  3097. /* We store the address number in data4. */
  3098. if (addr_num >= MAX_IP_ADDR)
  3099. return EINVAL;
  3100. if (addr_len > sizeof(ipmi_addr_t))
  3101. return EINVAL;
  3102. if (msg->data_len > IPMI_MAX_MSG_LENGTH)
  3103. return EINVAL;
  3104. lan = (lan_data_t *) ipmi->con_data;
  3105. if (lan->in_cleanup)
  3106. return ECANCELED;
  3107. /* Odd netfns are responses or unacknowledged data. Just send
  3108. them. */
  3109. if (msg->netfn & 1)
  3110. return lan_send_addr(lan, addr, addr_len, msg, 0, addr_num, NULL);
  3111. info = ipmi_mem_alloc(sizeof(*info));
  3112. if (!info)
  3113. return ENOMEM;
  3114. memset(info, 0, sizeof(*info));
  3115. /* Put it in the list first. */
  3116. info->ipmi = ipmi;
  3117. info->cancelled = 0;
  3118. rv = ipmi->os_hnd->alloc_timer(ipmi->os_hnd, &(info->timer));
  3119. if (rv) {
  3120. ipmi_mem_free(info);
  3121. return rv;
  3122. }
  3123. ipmi_lock(lan->seq_num_lock);
  3124. if (lan->outstanding_msg_count >= 60) {
  3125. rv = EAGAIN;
  3126. goto out_unlock;
  3127. }
  3128. rspi->data4 = (void *) (long) addr_num;
  3129. rv = handle_msg_send(info, addr_num, addr, addr_len, msg,
  3130. rsp_handler, rspi, 0);
  3131. /* handle_msg_send handles freeing the timer and info on an error */
  3132. info = NULL;
  3133. if (! rv)
  3134. lan->outstanding_msg_count++;
  3135. ipmi_unlock(lan->seq_num_lock);
  3136. return rv;
  3137. out_unlock:
  3138. ipmi_unlock(lan->seq_num_lock);
  3139. if (rv) {
  3140. if (info) {
  3141. if (info->timer)
  3142. ipmi->os_hnd->free_timer(ipmi->os_hnd, info->timer);
  3143. ipmi_mem_free(info);
  3144. }
  3145. }
  3146. return rv;
  3147. }
  3148. static int
  3149. lan_send_command_option(ipmi_con_t *ipmi,
  3150. const ipmi_addr_t *addr,
  3151. unsigned int addr_len,
  3152. const ipmi_msg_t *msg,
  3153. const ipmi_con_option_t *options,
  3154. ipmi_ll_rsp_handler_t rsp_handler,
  3155. ipmi_msgi_t *trspi)
  3156. {
  3157. lan_timer_info_t *info;
  3158. lan_data_t *lan;
  3159. int rv;
  3160. ipmi_msgi_t *rspi = trspi;
  3161. int side_effects = 0;
  3162. int i;
  3163. if (addr_len > sizeof(ipmi_addr_t))
  3164. return EINVAL;
  3165. if (msg->data_len > IPMI_MAX_MSG_LENGTH)
  3166. return EINVAL;
  3167. lan = (lan_data_t *) ipmi->con_data;
  3168. /* Odd netfns are responses or unacknowledged data. Just send
  3169. them. */
  3170. if (msg->netfn & 1) {
  3171. int dummy_send_ip;
  3172. return lan_send(lan, addr, addr_len, msg, 0, &dummy_send_ip, options);
  3173. }
  3174. if (options) {
  3175. for (i=0; options[i].option != IPMI_CON_OPTION_LIST_END; i++) {
  3176. if (options[i].option == IPMI_CON_MSG_OPTION_SIDE_EFFECTS)
  3177. side_effects = options[i].ival;
  3178. }
  3179. }
  3180. if (!rspi) {
  3181. rspi = ipmi_mem_alloc(sizeof(*rspi));
  3182. if (!rspi)
  3183. return ENOMEM;
  3184. }
  3185. info = ipmi_mem_alloc(sizeof(*info));
  3186. if (!info) {
  3187. rv = ENOMEM;
  3188. goto out_unlock2;
  3189. }
  3190. memset(info, 0, sizeof(*info));
  3191. /* Put it in the list first. */
  3192. info->ipmi = ipmi;
  3193. info->cancelled = 0;
  3194. rv = ipmi->os_hnd->alloc_timer(ipmi->os_hnd, &(info->timer));
  3195. if (rv)
  3196. goto out_unlock;
  3197. ipmi_lock(lan->seq_num_lock);
  3198. if (lan->outstanding_msg_count >= lan->max_outstanding_msg_count) {
  3199. lan_wait_queue_t *q_item;
  3200. q_item = ipmi_mem_alloc(sizeof(*q_item));
  3201. if (!q_item) {
  3202. ipmi->os_hnd->free_timer(ipmi->os_hnd, info->timer);
  3203. rv = ENOMEM;
  3204. goto out_unlock;
  3205. }
  3206. q_item->info = info;
  3207. memcpy(&(q_item->addr), addr, addr_len);
  3208. q_item->addr_len = addr_len;
  3209. memcpy(&q_item->msg, msg, sizeof(q_item->msg));
  3210. q_item->msg.data = q_item->data;
  3211. memcpy(q_item->data, msg->data, msg->data_len);
  3212. q_item->rsp_handler = rsp_handler;
  3213. q_item->rsp_item = rspi;
  3214. q_item->side_effects = side_effects;
  3215. /* Add it to the end of the queue. */
  3216. q_item->next = NULL;
  3217. if (lan->wait_q_tail == NULL) {
  3218. lan->wait_q_tail = q_item;
  3219. lan->wait_q = q_item;
  3220. } else {
  3221. lan->wait_q_tail->next = q_item;
  3222. lan->wait_q_tail = q_item;
  3223. }
  3224. goto out_unlock;
  3225. }
  3226. rv = handle_msg_send(info, -1, addr, addr_len, msg,
  3227. rsp_handler, rspi, side_effects);
  3228. /* handle_msg_send handles freeing the timer and info on an error */
  3229. info = NULL;
  3230. if (!rv)
  3231. lan->outstanding_msg_count++;
  3232. else if (!trspi && rspi)
  3233. /* If we allocated an rspi, free it on error. */
  3234. ipmi_mem_free(rspi);
  3235. ipmi_unlock(lan->seq_num_lock);
  3236. return rv;
  3237. out_unlock:
  3238. ipmi_unlock(lan->seq_num_lock);
  3239. if (rv) {
  3240. if (info) {
  3241. if (info->timer)
  3242. ipmi->os_hnd->free_timer(ipmi->os_hnd, info->timer);
  3243. ipmi_mem_free(info);
  3244. }
  3245. }
  3246. out_unlock2:
  3247. if (rv) {
  3248. /* If we allocated an rspi, free it. */
  3249. if (!trspi && rspi)
  3250. ipmi_mem_free(rspi);
  3251. }
  3252. return rv;
  3253. }
  3254. static int
  3255. lan_send_command(ipmi_con_t *ipmi,
  3256. const ipmi_addr_t *addr,
  3257. unsigned int addr_len,
  3258. const ipmi_msg_t *msg,
  3259. ipmi_ll_rsp_handler_t rsp_handler,
  3260. ipmi_msgi_t *trspi)
  3261. {
  3262. return lan_send_command_option(ipmi, addr, addr_len, msg, NULL,
  3263. rsp_handler, trspi);
  3264. }
  3265. static int
  3266. lan_send_response(ipmi_con_t *ipmi,
  3267. const ipmi_addr_t *addr,
  3268. unsigned int addr_len,
  3269. const ipmi_msg_t *msg,
  3270. long sequence)
  3271. {
  3272. return ENOSYS;
  3273. }
  3274. static int
  3275. lan_register_for_command(ipmi_con_t *ipmi,
  3276. unsigned char netfn,
  3277. unsigned char cmd,
  3278. ipmi_ll_cmd_handler_t handler,
  3279. void *cmd_data,
  3280. void *data2,
  3281. void *data3)
  3282. {
  3283. return ENOSYS;
  3284. }
  3285. static int
  3286. lan_deregister_for_command(ipmi_con_t *ipmi,
  3287. unsigned char netfn,
  3288. unsigned char cmd)
  3289. {
  3290. return ENOSYS;
  3291. }
  3292. static unsigned int
  3293. lan_get_num_ports(ipmi_con_t *ipmi)
  3294. {
  3295. lan_data_t *lan = (lan_data_t *) ipmi->con_data;
  3296. return lan->cparm.num_ip_addr;
  3297. }
  3298. static int
  3299. lan_get_port_info(ipmi_con_t *ipmi, unsigned int port,
  3300. char *info, int *info_len)
  3301. {
  3302. lan_data_t *lan = (lan_data_t *) ipmi->con_data;
  3303. sockaddr_ip_t *a;
  3304. int count = 0;
  3305. int len = *info_len;
  3306. if (port > lan->cparm.num_ip_addr)
  3307. return EINVAL;
  3308. a = &(lan->cparm.ip_addr[port]);
  3309. if (lan->ip[port].working_authtype == IPMI_AUTHTYPE_RMCP_PLUS)
  3310. count = snprintf(info, len, "rmcp+: ");
  3311. else
  3312. count = snprintf(info, len, "rmcp: ");
  3313. switch (a->s_ipsock.s_addr.sa_family) {
  3314. case PF_INET:
  3315. {
  3316. struct sockaddr_in *ip = &a->s_ipsock.s_addr4;
  3317. char buf[INET_ADDRSTRLEN];
  3318. inet_ntop(AF_INET, &ip->sin_addr, buf, sizeof(buf));
  3319. count += snprintf(info+count, len-count, "inet:%s:%d",
  3320. buf, ntohs(ip->sin_port));
  3321. }
  3322. break;
  3323. #ifdef PF_INET6
  3324. case PF_INET6:
  3325. {
  3326. struct sockaddr_in6 *ip = &a->s_ipsock.s_addr6;
  3327. char buf[INET6_ADDRSTRLEN];
  3328. inet_ntop(AF_INET6, &ip->sin6_addr, buf, sizeof(buf));
  3329. count += snprintf(info+count, len-count, "inet6:%s:%d",
  3330. buf, ntohs(ip->sin6_port));
  3331. }
  3332. break;
  3333. #endif
  3334. default:
  3335. count += snprintf(info+count, len-count, "invalid");
  3336. break;
  3337. }
  3338. *info_len = count;
  3339. return 0;
  3340. }
  3341. static void *
  3342. auth_alloc(void *info, int size)
  3343. {
  3344. return ipmi_mem_alloc(size);
  3345. }
  3346. static void
  3347. auth_free(void *info, void *data)
  3348. {
  3349. ipmi_mem_free(data);
  3350. }
  3351. /* Send the final close session to shut the connection down. */
  3352. static void
  3353. send_close_session(ipmi_con_t *ipmi, lan_data_t *lan, int addr_num)
  3354. {
  3355. ipmi_msg_t msg;
  3356. unsigned char data[4];
  3357. ipmi_system_interface_addr_t si;
  3358. si.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
  3359. si.channel = 0xf;
  3360. si.lun = 0;
  3361. msg.netfn = IPMI_APP_NETFN;
  3362. msg.cmd = IPMI_CLOSE_SESSION_CMD;
  3363. msg.data_len = 4;
  3364. msg.data = data;
  3365. if (lan->ip[addr_num].working_authtype == IPMI_AUTHTYPE_RMCP_PLUS)
  3366. ipmi_set_uint32(data, lan->ip[addr_num].mgsys_session_id);
  3367. else
  3368. ipmi_set_uint32(data, lan->ip[addr_num].session_id);
  3369. lan_send_addr(lan, (ipmi_addr_t *) &si, sizeof(si), &msg, 0, addr_num,
  3370. NULL);
  3371. }
  3372. typedef struct lan_unreg_stat_info_s
  3373. {
  3374. lan_data_t *lan;
  3375. ipmi_ll_stat_info_t *cmpinfo;
  3376. int found;
  3377. } lan_unreg_stat_info_t;
  3378. static int
  3379. lan_unreg_stat_info(void *cb_data, void *item1, void *item2)
  3380. {
  3381. ipmi_ll_stat_info_t *info = item2;
  3382. lan_stat_info_t *stat = item1;
  3383. lan_unreg_stat_info_t *sinfo = cb_data;
  3384. int i;
  3385. if (!sinfo->cmpinfo || (sinfo->cmpinfo == info)) {
  3386. locked_list_remove(sinfo->lan->lan_stat_list, stat, info);
  3387. for (i=0; i<NUM_STATS; i++)
  3388. if (stat->stats[i]) {
  3389. ipmi_ll_con_stat_call_unregister(info, stat->stats[i]);
  3390. stat->stats[i] = NULL;
  3391. }
  3392. ipmi_mem_free(stat);
  3393. sinfo->found = 1;
  3394. }
  3395. return LOCKED_LIST_ITER_CONTINUE;
  3396. }
  3397. static void
  3398. cleanup_con(ipmi_con_t *ipmi)
  3399. {
  3400. lan_data_t *lan = NULL;
  3401. unsigned int i;
  3402. if (ipmi) {
  3403. lan = (lan_data_t *) ipmi->con_data;
  3404. ipmi_con_attr_cleanup(ipmi);
  3405. if (ipmi->name) {
  3406. ipmi_mem_free(ipmi->name);
  3407. ipmi->name = NULL;
  3408. }
  3409. ipmi_mem_free(ipmi);
  3410. }
  3411. if (lan) {
  3412. /* This is only called in the case of an error at startup, so
  3413. there is no need to remove it from the LAN lists (hashes),
  3414. because it won't be there yet. */
  3415. for (i=0; i<lan->cparm.num_ip_addr; i++) {
  3416. if (lan->cparm.ip_addr_str[i])
  3417. ipmi_mem_free(lan->cparm.ip_addr_str[i]);
  3418. if (lan->cparm.ip_port_str[i])
  3419. ipmi_mem_free(lan->cparm.ip_port_str[i]);
  3420. }
  3421. if (lan->lan_stat_list) {
  3422. lan_unreg_stat_info_t sinfo;
  3423. sinfo.lan = lan;
  3424. sinfo.cmpinfo = NULL;
  3425. sinfo.found = 0;
  3426. locked_list_iterate(lan->lan_stat_list, lan_unreg_stat_info,
  3427. &sinfo);
  3428. locked_list_destroy(lan->lan_stat_list);
  3429. }
  3430. if (lan->con_change_lock)
  3431. ipmi_destroy_lock(lan->con_change_lock);
  3432. if (lan->ip_lock)
  3433. ipmi_destroy_lock(lan->ip_lock);
  3434. if (lan->con_change_handlers)
  3435. locked_list_destroy(lan->con_change_handlers);
  3436. if (lan->event_handlers)
  3437. locked_list_destroy(lan->event_handlers);
  3438. if (lan->ipmb_change_handlers)
  3439. locked_list_destroy(lan->ipmb_change_handlers);
  3440. if (lan->seq_num_lock)
  3441. ipmi_destroy_lock(lan->seq_num_lock);
  3442. if (lan->fd)
  3443. release_lan_fd(lan->fd, lan->fd_slot);
  3444. if (lan->authdata)
  3445. ipmi_auths[lan->chosen_authtype].authcode_cleanup(lan->authdata);
  3446. for (i=0; i<MAX_IP_ADDR; i++) {
  3447. if (lan->ip[i].conf_data)
  3448. lan->ip[i].conf_info->conf_free(ipmi, lan->ip[i].conf_data);
  3449. if (lan->ip[i].integ_data)
  3450. lan->ip[i].integ_info->integ_free(ipmi, lan->ip[i].integ_data);
  3451. }
  3452. /* paranoia */
  3453. memset(lan->cparm.password, 0, sizeof(lan->cparm.password));
  3454. memset(lan->cparm.bmc_key, 0, sizeof(lan->cparm.bmc_key));
  3455. ipmi_mem_free(lan);
  3456. }
  3457. }
  3458. static void
  3459. lan_cleanup(ipmi_con_t *ipmi)
  3460. {
  3461. lan_data_t *lan = ipmi->con_data;
  3462. int rv;
  3463. unsigned int i;
  3464. /* After this point no other operations can occur on this ipmi
  3465. interface, so it's safe. */
  3466. for (i=0; i<lan->cparm.num_ip_addr; i++)
  3467. send_close_session(ipmi, lan, i);
  3468. lan->in_cleanup = 1;
  3469. ipmi_lock(lan->seq_num_lock);
  3470. for (i=0; i<64; i++) {
  3471. if (lan->seq_table[i].inuse) {
  3472. ipmi_ll_rsp_handler_t handler;
  3473. ipmi_msgi_t *rspi;
  3474. lan_timer_info_t *info;
  3475. rv = ipmi->os_hnd->stop_timer(ipmi->os_hnd,
  3476. lan->seq_table[i].timer);
  3477. rspi = lan->seq_table[i].rsp_item;
  3478. if (lan->seq_table[i].use_orig_addr) {
  3479. /* We did an address translation, so translate back. */
  3480. memcpy(&rspi->addr, &lan->seq_table[i].orig_addr,
  3481. lan->seq_table[i].orig_addr_len);
  3482. rspi->addr_len = lan->seq_table[i].orig_addr_len;
  3483. } else {
  3484. memcpy(&rspi->addr, &(lan->seq_table[i].addr),
  3485. lan->seq_table[i].addr_len);
  3486. rspi->addr_len = lan->seq_table[i].addr_len;
  3487. }
  3488. handler = lan->seq_table[i].rsp_handler;
  3489. info = lan->seq_table[i].timer_info;
  3490. rspi->msg.netfn = lan->seq_table[i].msg.netfn | 1;
  3491. rspi->msg.cmd = lan->seq_table[i].msg.cmd;
  3492. rspi->msg.data = rspi->data;
  3493. rspi->data[0] = IPMI_UNKNOWN_ERR_CC;
  3494. rspi->msg.data_len = 1;
  3495. lan->seq_table[i].inuse = 0;
  3496. /* Wait until here to free the info, as we use it above.
  3497. But we must be holding the lock while we do this. */
  3498. if (rv)
  3499. info->cancelled = 1;
  3500. else {
  3501. ipmi->os_hnd->free_timer(ipmi->os_hnd, info->timer);
  3502. ipmi_mem_free(info);
  3503. }
  3504. ipmi_unlock(lan->seq_num_lock);
  3505. /* The unlock is safe here because the connection is no
  3506. longer valid and thus nothing else can really happen on
  3507. this connection. Sends will fail and receives will not
  3508. validate. */
  3509. ipmi_handle_rsp_item(NULL, rspi, handler);
  3510. ipmi_lock(lan->seq_num_lock);
  3511. }
  3512. }
  3513. while (lan->wait_q != NULL) {
  3514. lan_wait_queue_t *q_item;
  3515. q_item = lan->wait_q;
  3516. lan->wait_q = q_item->next;
  3517. ipmi->os_hnd->free_timer(ipmi->os_hnd, q_item->info->timer);
  3518. ipmi_unlock(lan->seq_num_lock);
  3519. q_item->msg.netfn |= 1; /* Convert it to a response. */
  3520. q_item->msg.data[0] = IPMI_UNKNOWN_ERR_CC;
  3521. q_item->msg.data_len = 1;
  3522. ipmi_handle_rsp_item_copyall(ipmi, q_item->rsp_item,
  3523. &q_item->addr, q_item->addr_len,
  3524. &q_item->msg, q_item->rsp_handler);
  3525. ipmi_lock(lan->seq_num_lock);
  3526. ipmi_mem_free(q_item->info);
  3527. ipmi_mem_free(q_item);
  3528. }
  3529. if (lan->audit_info) {
  3530. rv = ipmi->os_hnd->stop_timer(ipmi->os_hnd, lan->audit_timer);
  3531. if (rv)
  3532. lan->audit_info->cancelled = 1;
  3533. else {
  3534. ipmi->os_hnd->free_timer(ipmi->os_hnd, lan->audit_timer);
  3535. ipmi_mem_free(lan->audit_info);
  3536. }
  3537. }
  3538. ipmi_unlock(lan->seq_num_lock);
  3539. if (lan->close_done)
  3540. lan->close_done(ipmi, lan->close_cb_data);
  3541. if (ipmi->oem_data_cleanup)
  3542. ipmi->oem_data_cleanup(ipmi);
  3543. cleanup_con(ipmi);
  3544. }
  3545. static int
  3546. lan_close_connection_done(ipmi_con_t *ipmi,
  3547. ipmi_ll_con_closed_cb handler,
  3548. void *cb_data)
  3549. {
  3550. lan_data_t *lan;
  3551. if (! lan_valid_ipmi(ipmi))
  3552. return EINVAL;
  3553. lan = (lan_data_t *) ipmi->con_data;
  3554. ipmi_lock(lan_list_lock);
  3555. if (lan->users > 1) {
  3556. /* The connection has been reused, just report it going
  3557. down. */
  3558. lan->users--;
  3559. ipmi_unlock(lan_list_lock);
  3560. if (handler)
  3561. handler(ipmi, cb_data);
  3562. lan_put(ipmi);
  3563. return 0;
  3564. }
  3565. /* Once we begin the shutdown process, we don't want anyone else
  3566. reusing the connection. */
  3567. lan_remove_con_nolock(lan);
  3568. ipmi_unlock(lan_list_lock);
  3569. lan->close_done = handler;
  3570. lan->close_cb_data = cb_data;
  3571. /* Put it once for the lan_valid_ipmi() call, then once to
  3572. actually destroy it. */
  3573. lan_put(ipmi);
  3574. lan_put(ipmi);
  3575. return 0;
  3576. }
  3577. static int
  3578. lan_close_connection(ipmi_con_t *ipmi)
  3579. {
  3580. return lan_close_connection_done(ipmi, NULL, NULL);
  3581. }
  3582. static void
  3583. handle_connected(ipmi_con_t *ipmi, int err, int addr_num)
  3584. {
  3585. lan_data_t *lan;
  3586. if (!ipmi)
  3587. return;
  3588. lan = (lan_data_t *) ipmi->con_data;
  3589. /* This should be occurring single-threaded (the IP is down and is
  3590. being brought back up or is initially coming up), so no need
  3591. for a lock here. */
  3592. /* Make sure session data is reset on an error. */
  3593. if (err)
  3594. reset_session_data(lan, addr_num);
  3595. ipmi_lock(lan->ip_lock);
  3596. ipmi_lock(lan->con_change_lock);
  3597. ipmi_unlock(lan->ip_lock);
  3598. call_con_change_handlers(lan, err, addr_num, lan->connected);
  3599. ipmi_unlock(lan->con_change_lock);
  3600. }
  3601. static void
  3602. finish_connection(ipmi_con_t *ipmi, lan_data_t *lan, int addr_num)
  3603. {
  3604. lan->connected = 1;
  3605. connection_up(lan, addr_num, 1);
  3606. if (! lan->initialized) {
  3607. lan->initialized = 1;
  3608. handle_connected(ipmi, 0, addr_num);
  3609. }
  3610. }
  3611. static void
  3612. lan_set_ipmb_addr(ipmi_con_t *ipmi,
  3613. const unsigned char ipmb_addr[],
  3614. unsigned int num_ipmb_addr,
  3615. int active,
  3616. unsigned int hacks)
  3617. {
  3618. lan_data_t *lan = (lan_data_t *) ipmi->con_data;
  3619. int changed = 0;
  3620. unsigned int i;
  3621. for (i=0; i<num_ipmb_addr && i<MAX_IPMI_USED_CHANNELS; i++) {
  3622. if (! ipmb_addr[i])
  3623. continue;
  3624. if (lan->slave_addr[i] != ipmb_addr[i]) {
  3625. lan->slave_addr[i] = ipmb_addr[i];
  3626. ipmi->ipmb_addr[i] = ipmb_addr[i];
  3627. changed = 1;
  3628. }
  3629. }
  3630. if (changed || (lan->is_active != active)) {
  3631. lan->is_active = active;
  3632. ipmi->hacks = hacks;
  3633. call_ipmb_change_handlers(lan, 0, ipmb_addr, num_ipmb_addr,
  3634. active, hacks);
  3635. }
  3636. }
  3637. static void
  3638. handle_ipmb_addr(ipmi_con_t *ipmi,
  3639. int err,
  3640. const unsigned char ipmb_addr[],
  3641. unsigned int num_ipmb_addr,
  3642. int active,
  3643. unsigned int hacks,
  3644. void *cb_data)
  3645. {
  3646. lan_data_t *lan;
  3647. unsigned int addr_num = (unsigned long) cb_data;
  3648. unsigned int i;
  3649. if (err) {
  3650. handle_connected(ipmi, err, addr_num);
  3651. return;
  3652. }
  3653. if (!ipmi) {
  3654. handle_connected(ipmi, ECANCELED, addr_num);
  3655. return;
  3656. }
  3657. lan = (lan_data_t *) ipmi->con_data;
  3658. for (i=0; i<num_ipmb_addr && i<MAX_IPMI_USED_CHANNELS; i++) {
  3659. if (! ipmb_addr[i])
  3660. continue;
  3661. lan->slave_addr[i] = ipmb_addr[i];
  3662. ipmi->ipmb_addr[i] = ipmb_addr[i];
  3663. }
  3664. lan->is_active = active;
  3665. ipmi->hacks = hacks;
  3666. finish_connection(ipmi, lan, addr_num);
  3667. call_ipmb_change_handlers(lan, err, ipmb_addr, num_ipmb_addr,
  3668. active, hacks);
  3669. }
  3670. static int
  3671. handle_dev_id(ipmi_con_t *ipmi, ipmi_msgi_t *rspi)
  3672. {
  3673. ipmi_msg_t *msg = &rspi->msg;
  3674. lan_data_t *lan = NULL;
  3675. int err;
  3676. unsigned int manufacturer_id;
  3677. unsigned int product_id;
  3678. int addr_num = (long) rspi->data4;
  3679. if (!ipmi) {
  3680. err = ECANCELED;
  3681. goto out_err;
  3682. }
  3683. lan = (lan_data_t *) ipmi->con_data;
  3684. if (msg->data[0] != 0) {
  3685. err = IPMI_IPMI_ERR_VAL(msg->data[0]);
  3686. goto out_err;
  3687. }
  3688. if (msg->data_len < 12) {
  3689. err = EINVAL;
  3690. goto out_err;
  3691. }
  3692. manufacturer_id = (msg->data[7]
  3693. | (msg->data[8] << 8)
  3694. | (msg->data[9] << 16));
  3695. product_id = msg->data[10] | (msg->data[11] << 8);
  3696. if (!lan->oem_conn_handlers_called) {
  3697. lan->oem_conn_handlers_called = 1;
  3698. err = ipmi_check_oem_conn_handlers(ipmi, manufacturer_id, product_id);
  3699. if (err)
  3700. goto out_err;
  3701. if (ipmi->get_ipmb_addr) {
  3702. /* We have a way to fetch the IPMB address, do so. */
  3703. err = ipmi->get_ipmb_addr(ipmi, handle_ipmb_addr,
  3704. (void *) (long) addr_num);
  3705. if (err)
  3706. goto out_err;
  3707. } else
  3708. finish_connection(ipmi, lan, addr_num);
  3709. } else {
  3710. finish_connection(ipmi, lan, addr_num);
  3711. }
  3712. return IPMI_MSG_ITEM_NOT_USED;
  3713. out_err:
  3714. handle_connected(ipmi, err, addr_num);
  3715. return IPMI_MSG_ITEM_NOT_USED;
  3716. }
  3717. static int
  3718. send_get_dev_id(ipmi_con_t *ipmi, lan_data_t *lan, int addr_num,
  3719. ipmi_msgi_t *rspi)
  3720. {
  3721. ipmi_msg_t msg;
  3722. int rv;
  3723. ipmi_system_interface_addr_t addr;
  3724. addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
  3725. addr.channel = 0xf;
  3726. addr.lun = 0;
  3727. msg.cmd = IPMI_GET_DEVICE_ID_CMD;
  3728. msg.netfn = IPMI_APP_NETFN;
  3729. msg.data = NULL;
  3730. msg.data_len = 0;
  3731. rv = ipmi_lan_send_command_forceip(ipmi, addr_num,
  3732. (ipmi_addr_t *) &addr, sizeof(addr),
  3733. &msg, handle_dev_id, rspi);
  3734. return rv;
  3735. }
  3736. static void
  3737. lan_oem_done(ipmi_con_t *ipmi, void *cb_data)
  3738. {
  3739. lan_data_t *lan;
  3740. int rv;
  3741. ipmi_msgi_t *rspi = cb_data;
  3742. int addr_num = (long) rspi->data4;
  3743. if (! ipmi) {
  3744. ipmi_mem_free(rspi);
  3745. return;
  3746. }
  3747. lan = (lan_data_t *) ipmi->con_data;
  3748. rv = send_get_dev_id(ipmi, lan, addr_num, rspi);
  3749. if (rv) {
  3750. handle_connected(ipmi, rv, addr_num);
  3751. ipmi_mem_free(rspi);
  3752. }
  3753. }
  3754. static int
  3755. session_privilege_set(ipmi_con_t *ipmi, ipmi_msgi_t *rspi)
  3756. {
  3757. ipmi_msg_t *msg = &rspi->msg;
  3758. lan_data_t *lan;
  3759. int rv;
  3760. int addr_num = (long) rspi->data4;
  3761. if (!ipmi) {
  3762. handle_connected(ipmi, ECANCELED, addr_num);
  3763. goto out;
  3764. }
  3765. lan = (lan_data_t *) ipmi->con_data;
  3766. if (msg->data[0] != 0) {
  3767. handle_connected(ipmi, IPMI_IPMI_ERR_VAL(msg->data[0]), addr_num);
  3768. goto out;
  3769. }
  3770. if (msg->data_len < 2) {
  3771. handle_connected(ipmi, EINVAL, addr_num);
  3772. goto out;
  3773. }
  3774. if (lan->cparm.privilege != (unsigned int) (msg->data[1] & 0xf)) {
  3775. /* Requested privilege level did not match. */
  3776. handle_connected(ipmi, EINVAL, addr_num);
  3777. goto out;
  3778. }
  3779. rv = ipmi_conn_check_oem_handlers(ipmi, lan_oem_done, rspi);
  3780. if (rv) {
  3781. handle_connected(ipmi, rv, addr_num);
  3782. goto out;
  3783. }
  3784. return IPMI_MSG_ITEM_USED;
  3785. out:
  3786. return IPMI_MSG_ITEM_NOT_USED;
  3787. }
  3788. static int
  3789. send_set_session_privilege(ipmi_con_t *ipmi, lan_data_t *lan, int addr_num,
  3790. ipmi_msgi_t *rspi)
  3791. {
  3792. unsigned char data[1];
  3793. ipmi_msg_t msg;
  3794. int rv;
  3795. ipmi_system_interface_addr_t addr;
  3796. addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
  3797. addr.channel = 0xf;
  3798. addr.lun = 0;
  3799. data[0] = lan->cparm.privilege;
  3800. msg.cmd = IPMI_SET_SESSION_PRIVILEGE_CMD;
  3801. msg.netfn = IPMI_APP_NETFN;
  3802. msg.data = data;
  3803. msg.data_len = 1;
  3804. rv = ipmi_lan_send_command_forceip(ipmi, addr_num,
  3805. (ipmi_addr_t *) &addr, sizeof(addr),
  3806. &msg, session_privilege_set, rspi);
  3807. return rv;
  3808. }
  3809. static int
  3810. check_rakp_rsp(ipmi_con_t *ipmi,
  3811. ipmi_msg_t *msg,
  3812. char *caller,
  3813. unsigned int min_length,
  3814. int addr_num)
  3815. {
  3816. if (!ipmi) {
  3817. handle_connected(ipmi, ECANCELED, addr_num);
  3818. return ECANCELED;
  3819. }
  3820. if (msg->data_len < 2) {
  3821. ipmi_log(IPMI_LOG_ERR_INFO,
  3822. "%sipmi_lan.c(%s): Message data too short: %d",
  3823. IPMI_CONN_NAME(ipmi), caller, msg->data_len);
  3824. handle_connected(ipmi, EINVAL, addr_num);
  3825. return EINVAL;
  3826. }
  3827. if (msg->data[1]) {
  3828. /* Got an RMCP+ error. */
  3829. handle_connected(ipmi, IPMI_RMCPP_ERR_VAL(msg->data[1]), addr_num);
  3830. return EINVAL;
  3831. }
  3832. if (msg->data_len < min_length) {
  3833. ipmi_log(IPMI_LOG_ERR_INFO,
  3834. "%sipmi_lan.c(%s): Message data too short: %d",
  3835. IPMI_CONN_NAME(ipmi), caller, msg->data_len);
  3836. handle_connected(ipmi, EINVAL, addr_num);
  3837. return EINVAL;
  3838. }
  3839. return 0;
  3840. }
  3841. typedef struct auth_info_s
  3842. {
  3843. ipmi_msgi_t *rspi;
  3844. lan_data_t *lan;
  3845. } auth_info_t;
  3846. static void
  3847. rmcpp_auth_finished(ipmi_con_t *ipmi,
  3848. int err,
  3849. int addr_num,
  3850. void *cb_data)
  3851. {
  3852. auth_info_t *info = cb_data;
  3853. lan_data_t *lan = info->lan;
  3854. int rv = EINVAL;
  3855. if (!ipmi) {
  3856. handle_connected(lan->ipmi, ECANCELED, addr_num);
  3857. goto out;
  3858. }
  3859. if (err) {
  3860. handle_connected(lan->ipmi, err, addr_num);
  3861. goto out;
  3862. }
  3863. lan->ip[addr_num].session_id = lan->ip[addr_num].precon_session_id;
  3864. lan->ip[addr_num].mgsys_session_id
  3865. = lan->ip[addr_num].precon_mgsys_session_id;
  3866. lan->ip[addr_num].inbound_seq_num = 1;
  3867. lan->ip[addr_num].outbound_seq_num = 1;
  3868. lan->ip[addr_num].unauth_in_seq_num = 1;
  3869. lan->ip[addr_num].unauth_out_seq_num = 1;
  3870. /* We're up!. Start the session stuff. */
  3871. rv = send_set_session_privilege(ipmi, lan, addr_num, info->rspi);
  3872. if (rv) {
  3873. handle_connected(ipmi, rv, addr_num);
  3874. goto out;
  3875. }
  3876. out:
  3877. if (rv)
  3878. ipmi_free_msg_item(info->rspi);
  3879. ipmi_mem_free(info);
  3880. return;
  3881. }
  3882. static int
  3883. rmcpp_set_info(ipmi_con_t *ipmi,
  3884. int addr_num,
  3885. ipmi_rmcpp_auth_t *ainfo,
  3886. void *cb_data)
  3887. {
  3888. auth_info_t *info = cb_data;
  3889. lan_data_t *lan = info->lan;
  3890. int rv;
  3891. rv = lan->ip[addr_num].conf_info->conf_init
  3892. (ipmi, ainfo, &(lan->ip[addr_num].conf_data));
  3893. if (rv)
  3894. goto out;
  3895. rv = lan->ip[addr_num].integ_info->integ_init
  3896. (ipmi, ainfo, &(lan->ip[addr_num].integ_data));
  3897. if (rv)
  3898. goto out;
  3899. out:
  3900. return rv;
  3901. }
  3902. static int
  3903. got_rmcpp_open_session_rsp(ipmi_con_t *ipmi, ipmi_msgi_t *rspi)
  3904. {
  3905. ipmi_msg_t *msg = &rspi->msg;
  3906. lan_data_t *lan;
  3907. int addr_num = (long) rspi->data4;
  3908. uint32_t session_id;
  3909. uint32_t mgsys_session_id;
  3910. unsigned int privilege;
  3911. unsigned int auth, integ, conf;
  3912. ipmi_rmcpp_authentication_t *authp = NULL;
  3913. ipmi_rmcpp_confidentiality_t *confp = NULL;
  3914. ipmi_rmcpp_integrity_t *integp = NULL;
  3915. auth_info_t *info;
  3916. int rv;
  3917. if (check_rakp_rsp(ipmi, msg, "got_rmcpp_open_session_rsp", 36, addr_num))
  3918. goto out;
  3919. lan = (lan_data_t *) ipmi->con_data;
  3920. privilege = msg->data[2] & 0xf;
  3921. if (privilege != lan->cparm.privilege) {
  3922. ipmi_log(IPMI_LOG_ERR_INFO,
  3923. "%sipmi_lan.c(got_rmcpp_open_session_rsp): "
  3924. "Expected privilege %d, got %d",
  3925. IPMI_CONN_NAME(ipmi), lan->cparm.privilege, privilege);
  3926. handle_connected(ipmi, EINVAL, addr_num);
  3927. goto out;
  3928. }
  3929. session_id = ipmi_get_uint32(msg->data+4);
  3930. if (session_id != lan->ip[addr_num].precon_session_id) {
  3931. ipmi_log(IPMI_LOG_ERR_INFO,
  3932. "%sipmi_lan.c(got_rmcpp_open_session_rsp): "
  3933. " Got wrong session id: 0x%x",
  3934. IPMI_CONN_NAME(ipmi), session_id);
  3935. handle_connected(ipmi, EINVAL, addr_num);
  3936. goto out;
  3937. }
  3938. mgsys_session_id = ipmi_get_uint32(msg->data+8);
  3939. if (mgsys_session_id == 0) {
  3940. ipmi_log(IPMI_LOG_ERR_INFO,
  3941. "%sipmi_lan.c(got_rmcpp_open_session_rsp): "
  3942. "Got NULL mgd system session id", IPMI_CONN_NAME(ipmi));
  3943. handle_connected(ipmi, EINVAL, addr_num);
  3944. goto out;
  3945. }
  3946. lan->ip[addr_num].precon_mgsys_session_id = mgsys_session_id;
  3947. if ((msg->data[12] != 0) || (msg->data[15] != 8)) {
  3948. ipmi_log(IPMI_LOG_ERR_INFO,
  3949. "%sipmi_lan.c(got_rmcpp_open_session_rsp): "
  3950. "Got NULL or invalid authentication payload",
  3951. IPMI_CONN_NAME(ipmi));
  3952. handle_connected(ipmi, EINVAL, addr_num);
  3953. goto out;
  3954. }
  3955. auth = msg->data[16] & 0x3f;
  3956. if ((msg->data[20] != 1) || (msg->data[23] != 8)) {
  3957. ipmi_log(IPMI_LOG_ERR_INFO,
  3958. "%sipmi_lan.c(got_rmcpp_open_session_rsp): "
  3959. "Got NULL or invalid integrity payload",
  3960. IPMI_CONN_NAME(ipmi));
  3961. handle_connected(ipmi, EINVAL, addr_num);
  3962. goto out;
  3963. }
  3964. integ = msg->data[24] & 0x3f;
  3965. if ((msg->data[28] != 2) || (msg->data[31] != 8)) {
  3966. ipmi_log(IPMI_LOG_ERR_INFO,
  3967. "%sipmi_lan.c(got_rmcpp_open_session_rsp): "
  3968. "Got NULL or invalid confidentiality payload",
  3969. IPMI_CONN_NAME(ipmi));
  3970. handle_connected(ipmi, EINVAL, addr_num);
  3971. goto out;
  3972. }
  3973. conf = msg->data[32] & 0x3f;
  3974. if (auth >= 0x30) {
  3975. auth_entry_t *e = oem_auth_list;
  3976. while (e) {
  3977. if ((e->auth_num == auth)
  3978. && (memcmp(e->iana, lan->oem_iana, 3) == 0))
  3979. {
  3980. authp = e->auth;
  3981. break;
  3982. }
  3983. e = e->next;
  3984. }
  3985. } else
  3986. authp = auths[auth];
  3987. if (!authp) {
  3988. ipmi_log(IPMI_LOG_ERR_INFO,
  3989. "%sipmi_lan.c(got_rmcpp_open_session_rsp): "
  3990. "BMC returned an auth algorithm that wasn't supported: %d",
  3991. IPMI_CONN_NAME(ipmi), auth);
  3992. handle_connected(ipmi, EINVAL, addr_num);
  3993. goto out;
  3994. }
  3995. if (conf >= 0x30) {
  3996. conf_entry_t *e = oem_conf_list;
  3997. while (e) {
  3998. if ((e->conf_num == conf)
  3999. && (memcmp(e->iana, lan->oem_iana, 3) == 0))
  4000. {
  4001. confp = e->conf;
  4002. break;
  4003. }
  4004. e = e->next;
  4005. }
  4006. } else
  4007. confp = confs[conf];
  4008. if (!confp) {
  4009. ipmi_log(IPMI_LOG_ERR_INFO,
  4010. "%sipmi_lan.c(got_rmcpp_open_session_rsp): "
  4011. "BMC returned a conf algorithm that wasn't supported: %d",
  4012. IPMI_CONN_NAME(ipmi), conf);
  4013. handle_connected(ipmi, EINVAL, addr_num);
  4014. goto out;
  4015. }
  4016. if (integ >= 0x30) {
  4017. integ_entry_t *e = oem_integ_list;
  4018. while (e) {
  4019. if ((e->integ_num == integ)
  4020. && (memcmp(e->iana, lan->oem_iana, 3) == 0))
  4021. {
  4022. integp = e->integ;
  4023. break;
  4024. }
  4025. e = e->next;
  4026. }
  4027. } else
  4028. integp = integs[integ];
  4029. if (!integp) {
  4030. ipmi_log(IPMI_LOG_ERR_INFO,
  4031. "%sipmi_lan.c(got_rmcpp_open_session_rsp): "
  4032. "BMC returned an integ algorithm that wasn't supported: %d",
  4033. IPMI_CONN_NAME(ipmi), integ);
  4034. handle_connected(ipmi, EINVAL, addr_num);
  4035. goto out;
  4036. }
  4037. info = ipmi_mem_alloc(sizeof(*info));
  4038. if (!info) {
  4039. handle_connected(ipmi, ENOMEM, addr_num);
  4040. goto out;
  4041. }
  4042. lan->ip[addr_num].working_conf = conf;
  4043. lan->ip[addr_num].working_integ = integ;
  4044. lan->ip[addr_num].conf_info = confp;
  4045. lan->ip[addr_num].integ_info = integp;
  4046. lan->ip[addr_num].ainfo.lan = lan;
  4047. lan->ip[addr_num].ainfo.role = ((lan->cparm.name_lookup_only << 4)
  4048. | lan->cparm.privilege);
  4049. info->lan = lan;
  4050. info->rspi = rspi;
  4051. rv = authp->start_auth(ipmi, addr_num, lan->fd_slot,
  4052. &(lan->ip[addr_num].ainfo),
  4053. rmcpp_set_info, rmcpp_auth_finished,
  4054. info);
  4055. if (rv) {
  4056. ipmi_mem_free(info);
  4057. handle_connected(ipmi, rv, addr_num);
  4058. goto out;
  4059. }
  4060. return IPMI_MSG_ITEM_USED;
  4061. out:
  4062. return IPMI_MSG_ITEM_NOT_USED;
  4063. }
  4064. static int
  4065. send_rmcpp_open_session(ipmi_con_t *ipmi, lan_data_t *lan, ipmi_msgi_t *rspi,
  4066. int addr_num)
  4067. {
  4068. int rv;
  4069. unsigned char data[32];
  4070. ipmi_msg_t msg;
  4071. ipmi_rmcpp_addr_t addr;
  4072. memset(data, 0, sizeof(data));
  4073. data[0] = 0; /* Set to seq# by the formatting code. */
  4074. data[1] = lan->cparm.privilege;
  4075. ipmi_set_uint32(data+4, lan->ip[addr_num].precon_session_id);
  4076. data[8] = 0; /* auth algorithm */
  4077. if ((int) lan->cparm.auth == IPMI_LANP_AUTHENTICATION_ALGORITHM_BMCPICK)
  4078. data[11] = 0; /* Let the BMC pick */
  4079. else {
  4080. data[11] = 8;
  4081. data[12] = lan->cparm.auth;
  4082. }
  4083. data[16] = 1; /* integrity algorithm */
  4084. if ((int) lan->cparm.integ == IPMI_LANP_INTEGRITY_ALGORITHM_BMCPICK)
  4085. data[19] = 0; /* Let the BMC pick */
  4086. else {
  4087. data[19] = 8;
  4088. data[20] = lan->cparm.integ;
  4089. }
  4090. data[24] = 2; /* confidentiality algorithm */
  4091. if ((int) lan->cparm.conf == IPMI_LANP_CONFIDENTIALITY_ALGORITHM_BMCPICK)
  4092. data[27] = 0; /* Let the BMC pick */
  4093. else {
  4094. data[27] = 8;
  4095. data[28] = lan->cparm.conf;
  4096. }
  4097. msg.netfn = IPMI_RMCPP_DUMMY_NETFN;
  4098. msg.cmd = IPMI_RMCPP_PAYLOAD_TYPE_OPEN_SESSION_REQUEST;
  4099. msg.data = data;
  4100. msg.data_len = 32;
  4101. addr.addr_type = (IPMI_RMCPP_ADDR_START
  4102. + IPMI_RMCPP_PAYLOAD_TYPE_OPEN_SESSION_REQUEST);
  4103. rv = ipmi_lan_send_command_forceip(ipmi, addr_num,
  4104. (ipmi_addr_t *) &addr, sizeof(addr),
  4105. &msg, got_rmcpp_open_session_rsp, rspi);
  4106. return rv;
  4107. }
  4108. static int
  4109. start_rmcpp(ipmi_con_t *ipmi, lan_data_t *lan, ipmi_msgi_t *rspi, int addr_num)
  4110. {
  4111. int rv;
  4112. /* We don't really need to get the cipher suites, the user
  4113. requests them (or defaults them to the mandatory ones). */
  4114. lan->ip[addr_num].working_authtype = IPMI_AUTHTYPE_RMCP_PLUS;
  4115. lan->ip[addr_num].outbound_seq_num = 0;
  4116. lan->ip[addr_num].unauth_out_seq_num = 0;
  4117. lan->ip[addr_num].inbound_seq_num = 0;
  4118. lan->ip[addr_num].unauth_in_seq_num = 0;
  4119. /* Use our fd_slot in the fd for the session id, so we can look it
  4120. up quickly. */
  4121. lan->ip[addr_num].precon_session_id = lan->fd_slot + 1;
  4122. lan->ip[addr_num].working_conf = IPMI_LANP_CONFIDENTIALITY_ALGORITHM_NONE;
  4123. lan->ip[addr_num].working_integ = IPMI_LANP_INTEGRITY_ALGORITHM_NONE;
  4124. rv = send_rmcpp_open_session(ipmi, lan, rspi, addr_num);
  4125. if (rv) {
  4126. handle_connected(ipmi, rv, addr_num);
  4127. goto out;
  4128. }
  4129. return IPMI_MSG_ITEM_USED;
  4130. out:
  4131. return IPMI_MSG_ITEM_NOT_USED;
  4132. }
  4133. static int
  4134. session_activated(ipmi_con_t *ipmi, ipmi_msgi_t *rspi)
  4135. {
  4136. ipmi_msg_t *msg = &rspi->msg;
  4137. lan_data_t *lan;
  4138. int rv;
  4139. int addr_num = (long) rspi->data4;
  4140. if (!ipmi) {
  4141. handle_connected(ipmi, ECANCELED, addr_num);
  4142. goto out;
  4143. }
  4144. lan = (lan_data_t *) ipmi->con_data;
  4145. if (msg->data[0] != 0) {
  4146. handle_connected(ipmi, IPMI_IPMI_ERR_VAL(msg->data[0]), addr_num);
  4147. goto out;
  4148. }
  4149. if (msg->data_len < 11) {
  4150. handle_connected(ipmi, EINVAL, addr_num);
  4151. goto out;
  4152. }
  4153. lan->ip[addr_num].working_authtype = msg->data[1] & 0xf;
  4154. if ((lan->ip[addr_num].working_authtype != 0)
  4155. && (lan->ip[addr_num].working_authtype != lan->chosen_authtype))
  4156. {
  4157. /* Eh? It didn't return a valid authtype. */
  4158. handle_connected(ipmi, EINVAL, addr_num);
  4159. goto out;
  4160. }
  4161. lan->ip[addr_num].session_id = ipmi_get_uint32(msg->data+2);
  4162. lan->ip[addr_num].outbound_seq_num = ipmi_get_uint32(msg->data+6);
  4163. rv = send_set_session_privilege(ipmi, lan, addr_num, rspi);
  4164. if (rv) {
  4165. handle_connected(ipmi, rv, addr_num);
  4166. goto out;
  4167. }
  4168. return IPMI_MSG_ITEM_USED;
  4169. out:
  4170. return IPMI_MSG_ITEM_NOT_USED;
  4171. }
  4172. static int
  4173. send_activate_session(ipmi_con_t *ipmi, lan_data_t *lan, int addr_num,
  4174. ipmi_msgi_t *rspi)
  4175. {
  4176. unsigned char data[IPMI_MAX_MSG_LENGTH];
  4177. ipmi_msg_t msg;
  4178. int rv;
  4179. ipmi_system_interface_addr_t addr;
  4180. addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
  4181. addr.channel = 0xf;
  4182. addr.lun = 0;
  4183. data[0] = lan->chosen_authtype;
  4184. data[1] = lan->cparm.privilege;
  4185. memcpy(data+2, lan->challenge_string, 16);
  4186. ipmi_set_uint32(data+18, lan->ip[addr_num].inbound_seq_num);
  4187. msg.cmd = IPMI_ACTIVATE_SESSION_CMD;
  4188. msg.netfn = IPMI_APP_NETFN;
  4189. msg.data = data;
  4190. msg.data_len = 22;
  4191. rv = ipmi_lan_send_command_forceip(ipmi, addr_num,
  4192. (ipmi_addr_t *) &addr, sizeof(addr),
  4193. &msg, session_activated, rspi);
  4194. return rv;
  4195. }
  4196. static int
  4197. challenge_done(ipmi_con_t *ipmi, ipmi_msgi_t *rspi)
  4198. {
  4199. ipmi_msg_t *msg = &rspi->msg;
  4200. lan_data_t *lan;
  4201. int rv;
  4202. int addr_num = (long) rspi->data4;
  4203. if (!ipmi) {
  4204. handle_connected(ipmi, ECANCELED, addr_num);
  4205. goto out;
  4206. }
  4207. lan = (lan_data_t *) ipmi->con_data;
  4208. if (msg->data[0] != 0) {
  4209. handle_connected(ipmi, IPMI_IPMI_ERR_VAL(msg->data[0]), addr_num);
  4210. goto out;
  4211. }
  4212. if (msg->data_len < 21) {
  4213. handle_connected(ipmi, EINVAL, addr_num);
  4214. goto out;
  4215. }
  4216. /* Get the temporary session id. */
  4217. lan->ip[addr_num].session_id = ipmi_get_uint32(msg->data+1);
  4218. lan->ip[addr_num].outbound_seq_num = 0;
  4219. lan->ip[addr_num].working_authtype = lan->chosen_authtype;
  4220. memcpy(lan->challenge_string, msg->data+5, 16);
  4221. /* Get a random number of the other end to start sending me sequence
  4222. numbers at, but don't let it be zero. */
  4223. while (lan->ip[addr_num].inbound_seq_num == 0) {
  4224. rv = ipmi->os_hnd->get_random(ipmi->os_hnd,
  4225. &(lan->ip[addr_num].inbound_seq_num), 4);
  4226. if (rv) {
  4227. handle_connected(ipmi, rv, addr_num);
  4228. goto out;
  4229. }
  4230. }
  4231. rv = send_activate_session(ipmi, lan, addr_num, rspi);
  4232. if (rv) {
  4233. handle_connected(ipmi, rv, addr_num);
  4234. goto out;
  4235. }
  4236. return IPMI_MSG_ITEM_USED;
  4237. out:
  4238. return IPMI_MSG_ITEM_NOT_USED;
  4239. }
  4240. static int
  4241. send_challenge(ipmi_con_t *ipmi, lan_data_t *lan, int addr_num,
  4242. ipmi_msgi_t *rspi)
  4243. {
  4244. unsigned char data[IPMI_MAX_MSG_LENGTH];
  4245. ipmi_msg_t msg;
  4246. ipmi_system_interface_addr_t addr;
  4247. int rv;
  4248. addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
  4249. addr.channel = 0xf;
  4250. addr.lun = 0;
  4251. data[0] = lan->chosen_authtype;
  4252. msg.cmd = IPMI_GET_SESSION_CHALLENGE_CMD;
  4253. msg.netfn = IPMI_APP_NETFN;
  4254. msg.data = data;
  4255. msg.data_len = 1;
  4256. memcpy(data+1, lan->cparm.username, IPMI_USERNAME_MAX);
  4257. msg.data_len += IPMI_USERNAME_MAX;
  4258. rv = ipmi_lan_send_command_forceip(ipmi, addr_num,
  4259. (ipmi_addr_t *) &addr, sizeof(addr),
  4260. &msg, challenge_done, rspi);
  4261. return rv;
  4262. }
  4263. static int
  4264. auth_cap_done(ipmi_con_t *ipmi, ipmi_msgi_t *rspi)
  4265. {
  4266. ipmi_msg_t *msg = &rspi->msg;
  4267. lan_data_t *lan;
  4268. int rv;
  4269. int addr_num = (long) rspi->data4;
  4270. int supports_ipmi2;
  4271. int extended_capabilities_reported;
  4272. if (!ipmi) {
  4273. handle_connected(ipmi, ECANCELED, addr_num);
  4274. goto out;
  4275. }
  4276. lan = (lan_data_t *) ipmi->con_data;
  4277. if ((msg->data[0] != 0) || (msg->data_len < 9)) {
  4278. handle_connected(ipmi, EINVAL, addr_num);
  4279. goto out;
  4280. }
  4281. extended_capabilities_reported = (msg->data[2] & 0x80);
  4282. supports_ipmi2 = (msg->data[4] & 0x02);
  4283. if (extended_capabilities_reported && supports_ipmi2) {
  4284. /* We have RMCP+ support! Use it. */
  4285. lan->use_two_keys = (msg->data[3] >> 5) & 1;
  4286. memcpy(lan->oem_iana, msg->data+5, 3);
  4287. lan->oem_aux = msg->data[8];
  4288. return start_rmcpp(ipmi, lan, rspi, addr_num);
  4289. }
  4290. else if (supports_ipmi2)
  4291. {
  4292. /*
  4293. * The BMC has said that it supports RMCP+/IPMI 2.0 in the
  4294. * extended response fields, but has not indicated that we
  4295. * should USE the extended response fields! The SuperMicro
  4296. * AOC-IPMI20-E currently does this (April 2005), and will do
  4297. * so until they provide BMC firmware that supports RMCP+.
  4298. */
  4299. ipmi_log(IPMI_LOG_WARNING,
  4300. "%sipmi_lan.c(auth_cap_done): "
  4301. "BMC confused about RMCP+ support. Disabling RMCP+.",
  4302. IPMI_CONN_NAME(lan->ipmi));
  4303. }
  4304. if (lan->cparm.authtype == IPMI_AUTHTYPE_RMCP_PLUS) {
  4305. /* The user specified RMCP+, but the system doesn't have it. */
  4306. ipmi_log(IPMI_LOG_ERR_INFO,
  4307. "%sipmi_lan.c(auth_cap_done): "
  4308. "User requested RMCP+, but not supported",
  4309. IPMI_CONN_NAME(lan->ipmi));
  4310. handle_connected(ipmi, ENOENT, addr_num);
  4311. goto out;
  4312. }
  4313. memcpy(lan->oem_iana, msg->data+5, 3);
  4314. lan->oem_aux = msg->data[8];
  4315. if (lan->authdata) {
  4316. ipmi_auths[lan->chosen_authtype].authcode_cleanup(lan->authdata);
  4317. lan->authdata = NULL;
  4318. }
  4319. if ((int) lan->cparm.authtype == IPMI_AUTHTYPE_DEFAULT) {
  4320. /* Pick the most secure authentication type. */
  4321. if (msg->data[2] & (1 << IPMI_AUTHTYPE_MD5)) {
  4322. lan->chosen_authtype = IPMI_AUTHTYPE_MD5;
  4323. } else if (msg->data[2] & (1 << IPMI_AUTHTYPE_MD2)) {
  4324. lan->chosen_authtype = IPMI_AUTHTYPE_MD2;
  4325. } else if (msg->data[2] & (1 << IPMI_AUTHTYPE_STRAIGHT)) {
  4326. lan->chosen_authtype = IPMI_AUTHTYPE_STRAIGHT;
  4327. } else if (msg->data[2] & (1 << IPMI_AUTHTYPE_NONE)) {
  4328. lan->chosen_authtype = IPMI_AUTHTYPE_NONE;
  4329. } else {
  4330. ipmi_log(IPMI_LOG_ERR_INFO,
  4331. "%sipmi_lan.c(auth_cap_done): "
  4332. "No valid authentication supported",
  4333. IPMI_CONN_NAME(lan->ipmi));
  4334. handle_connected(ipmi, EINVAL, addr_num);
  4335. goto out;
  4336. }
  4337. } else {
  4338. if (!(msg->data[2] & (1 << lan->cparm.authtype))) {
  4339. ipmi_log(IPMI_LOG_ERR_INFO,
  4340. "%sipmi_lan.c(auth_cap_done): "
  4341. "Requested authentication not supported",
  4342. IPMI_CONN_NAME(lan->ipmi));
  4343. handle_connected(ipmi, EINVAL, addr_num);
  4344. goto out;
  4345. }
  4346. lan->chosen_authtype = lan->cparm.authtype;
  4347. }
  4348. rv = ipmi_auths[lan->chosen_authtype].authcode_init(lan->cparm.password,
  4349. &(lan->authdata),
  4350. NULL, auth_alloc,
  4351. auth_free);
  4352. if (rv) {
  4353. ipmi_log(IPMI_LOG_ERR_INFO,
  4354. "%sipmi_lan.c(auth_cap_done): "
  4355. "Unable to initialize authentication data: 0x%x",
  4356. IPMI_CONN_NAME(lan->ipmi), rv);
  4357. handle_connected(ipmi, rv, addr_num);
  4358. goto out;
  4359. }
  4360. rv = send_challenge(ipmi, lan, addr_num, rspi);
  4361. if (rv) {
  4362. ipmi_log(IPMI_LOG_ERR_INFO,
  4363. "%sipmi_lan.c(auth_cap_done): "
  4364. "Unable to send challenge command: 0x%x",
  4365. IPMI_CONN_NAME(lan->ipmi), rv);
  4366. handle_connected(ipmi, rv, addr_num);
  4367. goto out;
  4368. }
  4369. return IPMI_MSG_ITEM_USED;
  4370. out:
  4371. return IPMI_MSG_ITEM_NOT_USED;
  4372. }
  4373. static int
  4374. auth_cap_done_p(ipmi_con_t *ipmi, ipmi_msgi_t *rspi)
  4375. {
  4376. ipmi_msg_t *msg = &rspi->msg;
  4377. lan_data_t *lan;
  4378. int addr_num = (long) rspi->data4;
  4379. int rv;
  4380. if (!ipmi) {
  4381. handle_connected(ipmi, ECANCELED, addr_num);
  4382. goto out;
  4383. }
  4384. lan = (lan_data_t *) ipmi->con_data;
  4385. if ((msg->data[0] != 0) || (msg->data_len < 9)) {
  4386. /* Got an error, try it without the RMCP+ bit set. Some
  4387. systems incorrectly return errors when reserved data is
  4388. set. */
  4389. if (lan->cparm.authtype == IPMI_AUTHTYPE_RMCP_PLUS) {
  4390. /* The user specified RMCP+, but the system doesn't have it. */
  4391. ipmi_log(IPMI_LOG_ERR_INFO,
  4392. "%sipmi_lan.c(auth_cap_done_p): "
  4393. "Use requested RMCP+, but not supported",
  4394. IPMI_CONN_NAME(lan->ipmi));
  4395. handle_connected(ipmi, ENOENT, addr_num);
  4396. goto out;
  4397. }
  4398. rv = send_auth_cap(ipmi, lan, addr_num, 1);
  4399. if (rv) {
  4400. handle_connected(ipmi, rv, addr_num);
  4401. }
  4402. goto out;
  4403. }
  4404. return auth_cap_done(ipmi, rspi);
  4405. out:
  4406. return IPMI_MSG_ITEM_NOT_USED;
  4407. }
  4408. static int
  4409. send_auth_cap(ipmi_con_t *ipmi, lan_data_t *lan, int addr_num,
  4410. int force_ipmiv15)
  4411. {
  4412. unsigned char data[2];
  4413. ipmi_msg_t msg;
  4414. ipmi_system_interface_addr_t addr;
  4415. int rv;
  4416. ipmi_msgi_t *rspi;
  4417. ipmi_ll_rsp_handler_t rsp_handler;
  4418. /* FIXME - a system may only support RMCP+ and not RMCP. We need
  4419. a way to detect and handle that. */
  4420. rspi = ipmi_mem_alloc(sizeof(*rspi));
  4421. if (!rspi)
  4422. return ENOMEM;
  4423. addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
  4424. addr.channel = 0xf;
  4425. addr.lun = 0;
  4426. data[0] = 0xe;
  4427. data[1] = lan->cparm.privilege;
  4428. msg.cmd = IPMI_GET_CHANNEL_AUTH_CAPABILITIES_CMD;
  4429. msg.netfn = IPMI_APP_NETFN;
  4430. msg.data = data;
  4431. msg.data_len = 2;
  4432. if ((((int) lan->cparm.authtype == IPMI_AUTHTYPE_DEFAULT)
  4433. || ((int) lan->cparm.authtype == IPMI_AUTHTYPE_RMCP_PLUS))
  4434. && !force_ipmiv15)
  4435. {
  4436. rsp_handler = auth_cap_done_p;
  4437. data[0] |= 0x80; /* Get RMCP data. */
  4438. } else {
  4439. rsp_handler = auth_cap_done;
  4440. }
  4441. rv = ipmi_lan_send_command_forceip(ipmi, addr_num,
  4442. (ipmi_addr_t *) &addr, sizeof(addr),
  4443. &msg, rsp_handler, rspi);
  4444. if (rv)
  4445. ipmi_mem_free(rspi);
  4446. return rv;
  4447. }
  4448. static int
  4449. lan_start_con(ipmi_con_t *ipmi)
  4450. {
  4451. lan_data_t *lan = (lan_data_t *) ipmi->con_data;
  4452. int rv;
  4453. struct timeval timeout;
  4454. unsigned int i;
  4455. ipmi_lock(lan->ip_lock);
  4456. if (lan->started) {
  4457. /* Only allow started to be called once, but make sure the
  4458. connected callback gets called if started is called again
  4459. (assuming the connection is up). This lets multiple users
  4460. use the same connection. If the LAN is not connected, this
  4461. doesn't matter, the callback will be called properly
  4462. later. */
  4463. if (lan->connected) {
  4464. unsigned int i;
  4465. int port_err[MAX_IP_ADDR];
  4466. for (i=0; i<lan->cparm.num_ip_addr; i++)
  4467. port_err[i] = lan->ip[i].working ? 0 : EINVAL;
  4468. ipmi_lock(lan->con_change_lock);
  4469. ipmi_unlock(lan->ip_lock);
  4470. for (i=0; i<lan->cparm.num_ip_addr; i++)
  4471. call_con_change_handlers(lan, port_err[i], i, 1);
  4472. ipmi_unlock(lan->con_change_lock);
  4473. } else
  4474. ipmi_unlock(lan->ip_lock);
  4475. return 0;
  4476. }
  4477. /* Start the timer to audit the connections. */
  4478. lan->audit_info = ipmi_mem_alloc(sizeof(*(lan->audit_info)));
  4479. if (!lan->audit_info) {
  4480. rv = ENOMEM;
  4481. goto out_err;
  4482. }
  4483. lan->audit_info->cancelled = 0;
  4484. lan->audit_info->ipmi = ipmi;
  4485. rv = ipmi->os_hnd->alloc_timer(ipmi->os_hnd, &(lan->audit_timer));
  4486. if (rv)
  4487. goto out_err;
  4488. timeout.tv_sec = LAN_AUDIT_TIMEOUT / 1000000;
  4489. timeout.tv_usec = LAN_AUDIT_TIMEOUT % 1000000;
  4490. rv = ipmi->os_hnd->start_timer(ipmi->os_hnd,
  4491. lan->audit_timer,
  4492. &timeout,
  4493. audit_timeout_handler,
  4494. lan->audit_info);
  4495. if (rv) {
  4496. ipmi_mem_free(lan->audit_info);
  4497. lan->audit_info = NULL;
  4498. ipmi->os_hnd->free_timer(ipmi->os_hnd, lan->audit_timer);
  4499. lan->audit_timer = NULL;
  4500. goto out_err;
  4501. }
  4502. lan->started = 1;
  4503. ipmi_unlock(lan->ip_lock);
  4504. for (i=0; i<lan->cparm.num_ip_addr; i++)
  4505. /* Ignore failures, this gets retried. */
  4506. send_auth_cap(ipmi, lan, i, 0);
  4507. return 0;
  4508. out_err:
  4509. ipmi_unlock(lan->ip_lock);
  4510. return rv;
  4511. }
  4512. int
  4513. ipmi_lan_setup_con(struct in_addr *ip_addrs,
  4514. int *ports,
  4515. unsigned int num_ip_addrs,
  4516. unsigned int authtype,
  4517. unsigned int privilege,
  4518. void *username,
  4519. unsigned int username_len,
  4520. void *password,
  4521. unsigned int password_len,
  4522. os_handler_t *handlers,
  4523. void *user_data,
  4524. ipmi_con_t **new_con)
  4525. {
  4526. char s_ip_addrs[MAX_IP_ADDR][20];
  4527. char s_ports[MAX_IP_ADDR][10];
  4528. char *paddrs[MAX_IP_ADDR], *pports[MAX_IP_ADDR];
  4529. unsigned char *p;
  4530. unsigned int i;
  4531. int rv;
  4532. if ((num_ip_addrs < 1) || (num_ip_addrs > MAX_IP_ADDR))
  4533. return EINVAL;
  4534. for (i=0; i<num_ip_addrs; i++) {
  4535. p = (unsigned char *)&(ip_addrs[i]);
  4536. sprintf(s_ip_addrs[i], "%u.%u.%u.%u", *p, *(p+1), *(p+2), *(p+3));
  4537. sprintf(s_ports[i], "%u", ports[i]);
  4538. paddrs[i] = s_ip_addrs[i];
  4539. pports[i]= s_ports[i];
  4540. }
  4541. rv = ipmi_ip_setup_con(paddrs,
  4542. pports,
  4543. num_ip_addrs,
  4544. authtype,
  4545. privilege,
  4546. username,
  4547. username_len,
  4548. password,
  4549. password_len,
  4550. handlers,
  4551. user_data,
  4552. new_con);
  4553. return rv;
  4554. }
  4555. int
  4556. ipmi_ip_setup_con(char * const ip_addrs[],
  4557. char * const ports[],
  4558. unsigned int num_ip_addrs,
  4559. unsigned int authtype,
  4560. unsigned int privilege,
  4561. void *username,
  4562. unsigned int username_len,
  4563. void *password,
  4564. unsigned int password_len,
  4565. os_handler_t *handlers,
  4566. void *user_data,
  4567. ipmi_con_t **new_con)
  4568. {
  4569. ipmi_lanp_parm_t parms[6];
  4570. parms[0].parm_id = IPMI_LANP_PARMID_ADDRS;
  4571. parms[0].parm_data = (void *) ip_addrs;
  4572. parms[0].parm_data_len = num_ip_addrs;
  4573. parms[1].parm_id = IPMI_LANP_PARMID_PORTS;
  4574. parms[1].parm_data = (void *) ports;
  4575. parms[1].parm_data_len = num_ip_addrs;
  4576. parms[2].parm_id = IPMI_LANP_PARMID_AUTHTYPE;
  4577. parms[2].parm_val = authtype;
  4578. parms[3].parm_id = IPMI_LANP_PARMID_PRIVILEGE;
  4579. parms[3].parm_val = privilege;
  4580. parms[4].parm_id = IPMI_LANP_PARMID_USERNAME;
  4581. parms[4].parm_data = username;
  4582. parms[4].parm_data_len = username_len;
  4583. parms[5].parm_id = IPMI_LANP_PARMID_PASSWORD;
  4584. parms[5].parm_data = password;
  4585. parms[5].parm_data_len = password_len;
  4586. return ipmi_lanp_setup_con(parms, 6, handlers, user_data, new_con);
  4587. }
  4588. static lan_data_t *
  4589. find_matching_lan(lan_conn_parms_t *cparm)
  4590. {
  4591. lan_link_t *l;
  4592. lan_data_t *lan;
  4593. unsigned int idx;
  4594. /* Look in the first IP addresses list. */
  4595. idx = hash_lan_addr(&cparm->ip_addr[0].s_ipsock.s_addr);
  4596. ipmi_lock(lan_list_lock);
  4597. l = lan_ip_list[idx].next;
  4598. while (l->lan) {
  4599. lan = l->lan;
  4600. if (memcmp(&lan->cparm, cparm, sizeof(*cparm)) == 0) {
  4601. /* Parms match up, use it */
  4602. lan->users++;
  4603. ipmi_unlock(lan_list_lock);
  4604. return lan;
  4605. }
  4606. l = l->next;
  4607. }
  4608. ipmi_unlock(lan_list_lock);
  4609. return NULL;
  4610. }
  4611. static void
  4612. lan_use_connection(ipmi_con_t *ipmi)
  4613. {
  4614. lan_data_t *lan = ipmi->con_data;
  4615. ipmi_lock(lan_list_lock);
  4616. lan->users++;
  4617. ipmi_unlock(lan_list_lock);
  4618. }
  4619. static int
  4620. lan_register_stat_handler(ipmi_con_t *ipmi,
  4621. ipmi_ll_stat_info_t *info)
  4622. {
  4623. lan_stat_info_t *nstat;
  4624. lan_data_t *lan = ipmi->con_data;
  4625. int i;
  4626. nstat = ipmi_mem_alloc(sizeof(*nstat));
  4627. if (!nstat)
  4628. return ENOMEM;
  4629. memset(nstat, 0, sizeof(*nstat));
  4630. for (i=0; i<NUM_STATS; i++)
  4631. ipmi_ll_con_stat_call_register(info, lan_stat_names[i],
  4632. ipmi->name, &(nstat->stats[i]));
  4633. if (!locked_list_add(lan->lan_stat_list, nstat, info)) {
  4634. for (i=0; i<NUM_STATS; i++)
  4635. if (nstat->stats[i]) {
  4636. ipmi_ll_con_stat_call_unregister(info, nstat->stats[i]);
  4637. nstat->stats[i] = NULL;
  4638. }
  4639. ipmi_mem_free(nstat);
  4640. return ENOMEM;
  4641. }
  4642. return 0;
  4643. }
  4644. static int
  4645. lan_unregister_stat_handler(ipmi_con_t *ipmi,
  4646. ipmi_ll_stat_info_t *info)
  4647. {
  4648. lan_unreg_stat_info_t sinfo;
  4649. lan_data_t *lan = ipmi->con_data;
  4650. sinfo.lan = lan;
  4651. sinfo.cmpinfo = info;
  4652. sinfo.found = 0;
  4653. locked_list_iterate(lan->lan_stat_list, lan_unreg_stat_info,
  4654. &sinfo);
  4655. if (sinfo.found)
  4656. return 0;
  4657. else
  4658. return EINVAL;
  4659. }
  4660. static ipmi_args_t *get_startup_args(ipmi_con_t *ipmi);
  4661. static unsigned int conf_order[] = {
  4662. IPMI_LANP_CONFIDENTIALITY_ALGORITHM_AES_CBC_128
  4663. };
  4664. static unsigned int
  4665. most_secure_lanp_conf(void)
  4666. {
  4667. unsigned int i, v;
  4668. for (i=0; i<(sizeof(conf_order)/sizeof(unsigned int)); i++) {
  4669. v = conf_order[i];
  4670. if (confs[v])
  4671. return v;
  4672. }
  4673. return IPMI_LANP_CONFIDENTIALITY_ALGORITHM_NONE;
  4674. }
  4675. static unsigned int integ_order[] = {
  4676. IPMI_LANP_INTEGRITY_ALGORITHM_HMAC_SHA1_96,
  4677. IPMI_LANP_INTEGRITY_ALGORITHM_HMAC_MD5_128,
  4678. IPMI_LANP_INTEGRITY_ALGORITHM_MD5_128
  4679. };
  4680. static unsigned int
  4681. most_secure_lanp_integ(void)
  4682. {
  4683. unsigned int i, v;
  4684. for (i=0; i<(sizeof(integ_order)/sizeof(unsigned int)); i++) {
  4685. v = integ_order[i];
  4686. if (integs[v])
  4687. return v;
  4688. }
  4689. return IPMI_LANP_INTEGRITY_ALGORITHM_NONE;
  4690. }
  4691. static unsigned int auth_order[] = {
  4692. IPMI_LANP_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA1,
  4693. IPMI_LANP_AUTHENTICATION_ALGORITHM_RAKP_HMAC_MD5
  4694. };
  4695. static unsigned int
  4696. most_secure_lanp_auth(void)
  4697. {
  4698. unsigned int i, v;
  4699. for (i=0; i<(sizeof(auth_order)/sizeof(unsigned int)); i++) {
  4700. v = auth_order[i];
  4701. if (auths[v])
  4702. return v;
  4703. }
  4704. return IPMI_LANP_AUTHENTICATION_ALGORITHM_RAKP_NONE;
  4705. }
  4706. int
  4707. ipmi_lanp_setup_con(ipmi_lanp_parm_t *parms,
  4708. unsigned int num_parms,
  4709. os_handler_t *handlers,
  4710. void *user_data,
  4711. ipmi_con_t **new_con)
  4712. {
  4713. ipmi_con_t *ipmi = NULL;
  4714. lan_data_t *lan = NULL;
  4715. int rv;
  4716. unsigned int i;
  4717. unsigned int count;
  4718. struct sockaddr_in *pa;
  4719. char **ip_addrs = NULL;
  4720. char *tports[MAX_IP_ADDR];
  4721. char **ports = NULL;
  4722. lan_conn_parms_t cparm;
  4723. int max_outstanding_msg_count = DEFAULT_MAX_OUTSTANDING_MSG_COUNT;
  4724. memset(&cparm, 0, sizeof(cparm));
  4725. /* Pick some secure defaults. */
  4726. cparm.authtype = IPMI_AUTHTYPE_DEFAULT;
  4727. cparm.privilege = IPMI_PRIVILEGE_ADMIN;
  4728. cparm.conf = most_secure_lanp_conf();
  4729. cparm.integ = most_secure_lanp_integ();
  4730. cparm.auth = most_secure_lanp_auth();
  4731. cparm.name_lookup_only = 1;
  4732. for (i=0; i<num_parms; i++) {
  4733. switch (parms[i].parm_id) {
  4734. case IPMI_LANP_PARMID_AUTHTYPE:
  4735. cparm.authtype = parms[i].parm_val;
  4736. break;
  4737. case IPMI_LANP_PARMID_PRIVILEGE:
  4738. cparm.privilege = parms[i].parm_val;
  4739. break;
  4740. case IPMI_LANP_PARMID_PASSWORD:
  4741. if (parms[i].parm_data_len > sizeof(cparm.password))
  4742. return EINVAL;
  4743. memcpy(cparm.password, parms[i].parm_data, parms[i].parm_data_len);
  4744. cparm.password_len = parms[i].parm_data_len;
  4745. break;
  4746. case IPMI_LANP_PARMID_USERNAME:
  4747. if (parms[i].parm_data_len > sizeof(cparm.username))
  4748. return EINVAL;
  4749. memcpy(cparm.username, parms[i].parm_data, parms[i].parm_data_len);
  4750. cparm.username_len = parms[i].parm_data_len;
  4751. break;
  4752. case IPMI_LANP_PARMID_ADDRS:
  4753. if (cparm.num_ip_addr
  4754. && (cparm.num_ip_addr != parms[i].parm_data_len))
  4755. return EINVAL;
  4756. if (parms[i].parm_data_len > MAX_IP_ADDR)
  4757. return EINVAL;
  4758. ip_addrs = parms[i].parm_data;
  4759. cparm.num_ip_addr = parms[i].parm_data_len;
  4760. break;
  4761. case IPMI_LANP_PARMID_PORTS:
  4762. if (cparm.num_ip_addr
  4763. && (cparm.num_ip_addr != parms[i].parm_data_len))
  4764. return EINVAL;
  4765. if (parms[i].parm_data_len > MAX_IP_ADDR)
  4766. return EINVAL;
  4767. ports = parms[i].parm_data;
  4768. cparm.num_ip_addr = parms[i].parm_data_len;
  4769. break;
  4770. case IPMI_LANP_AUTHENTICATION_ALGORITHM:
  4771. cparm.auth = parms[i].parm_val;
  4772. if ((int) cparm.auth != IPMI_LANP_AUTHENTICATION_ALGORITHM_BMCPICK)
  4773. {
  4774. if (cparm.auth >= 64)
  4775. return EINVAL;
  4776. if ((cparm.auth < 0x30) && (!auths[cparm.auth]))
  4777. return ENOSYS;
  4778. }
  4779. break;
  4780. case IPMI_LANP_INTEGRITY_ALGORITHM:
  4781. cparm.integ = parms[i].parm_val;
  4782. if ((int) cparm.integ != IPMI_LANP_INTEGRITY_ALGORITHM_BMCPICK)
  4783. {
  4784. if (cparm.integ >= 64)
  4785. return EINVAL;
  4786. if (cparm.integ
  4787. && ((cparm.integ < 0x30) && (!integs[cparm.integ])))
  4788. return ENOSYS;
  4789. }
  4790. break;
  4791. case IPMI_LANP_CONFIDENTIALITY_ALGORITHM:
  4792. cparm.conf = parms[i].parm_val;
  4793. if ((int)cparm.conf != IPMI_LANP_CONFIDENTIALITY_ALGORITHM_BMCPICK)
  4794. {
  4795. if (cparm.conf >= 64)
  4796. return EINVAL;
  4797. if (cparm.conf
  4798. && ((cparm.conf < 0x30) && (!confs[cparm.conf])))
  4799. return ENOSYS;
  4800. }
  4801. break;
  4802. case IPMI_LANP_NAME_LOOKUP_ONLY:
  4803. cparm.name_lookup_only = parms[i].parm_val != 0;
  4804. break;
  4805. case IPMI_LANP_BMC_KEY:
  4806. if (parms[i].parm_data_len > sizeof(cparm.bmc_key))
  4807. return EINVAL;
  4808. memcpy(cparm.bmc_key, parms[i].parm_data, parms[i].parm_data_len);
  4809. cparm.bmc_key_len = parms[i].parm_data_len;
  4810. break;
  4811. case IPMI_LANP_MAX_OUTSTANDING_MSG_COUNT:
  4812. if ((parms[i].parm_val < 1)
  4813. || (parms[i].parm_val > MAX_POSSIBLE_OUTSTANDING_MSG_COUNT))
  4814. return EINVAL;
  4815. max_outstanding_msg_count = parms[i].parm_val;
  4816. break;
  4817. default:
  4818. return EINVAL;
  4819. }
  4820. }
  4821. if ((cparm.num_ip_addr == 0) || (ip_addrs == NULL))
  4822. return EINVAL;
  4823. if (((int) cparm.authtype != IPMI_AUTHTYPE_DEFAULT)
  4824. && (cparm.authtype != IPMI_AUTHTYPE_RMCP_PLUS)
  4825. && ((cparm.authtype >= MAX_IPMI_AUTHS)
  4826. || (ipmi_auths[cparm.authtype].authcode_init == NULL)))
  4827. return EINVAL;
  4828. if ((cparm.num_ip_addr < 1) || (cparm.num_ip_addr > MAX_IP_ADDR))
  4829. return EINVAL;
  4830. if (ports) {
  4831. for (i=0; i<MAX_IP_ADDR; i++)
  4832. tports[i] = ports[i];
  4833. ports = tports;
  4834. } else {
  4835. ports = tports;
  4836. for (i=0; i<MAX_IP_ADDR; i++)
  4837. ports[i] = NULL;
  4838. }
  4839. for (i=0; i<MAX_IP_ADDR; i++) {
  4840. if (!ports[i])
  4841. ports[i] = IPMI_LAN_STD_PORT_STR;
  4842. }
  4843. count = 0;
  4844. #ifdef HAVE_GETADDRINFO
  4845. for (i=0; i<cparm.num_ip_addr; i++) {
  4846. struct addrinfo hints, *res0;
  4847. memset(&hints, 0, sizeof(hints));
  4848. if (count == 0)
  4849. hints.ai_family = PF_UNSPEC;
  4850. else
  4851. {
  4852. /* Make sure all ip address is in the same protocol family*/
  4853. struct sockaddr_in *paddr;
  4854. paddr = (struct sockaddr_in *)&(cparm.ip_addr[0]);
  4855. hints.ai_family = paddr->sin_family;
  4856. }
  4857. hints.ai_socktype = SOCK_DGRAM;
  4858. rv = getaddrinfo(ip_addrs[i], ports[i], &hints, &res0);
  4859. if (rv)
  4860. return EINVAL;
  4861. /* Only get the first choices */
  4862. memcpy(&(cparm.ip_addr[count].s_ipsock), res0->ai_addr,
  4863. res0->ai_addrlen);
  4864. cparm.ip_addr[count].ip_addr_len = res0->ai_addrlen;
  4865. count++;
  4866. freeaddrinfo(res0);
  4867. }
  4868. #else
  4869. /* System does not support getaddrinfo, just for IPv4*/
  4870. for (i=0; i<cparm.num_ip_addr; i++) {
  4871. struct hostent *ent;
  4872. struct sockaddr_in *paddr;
  4873. ent = gethostbyname(ip_addrs[i]);
  4874. if (!ent)
  4875. return EINVAL;
  4876. paddr = (struct sockaddr_in *)&(cparm.ip_addr[i]);
  4877. paddr->sin_family = AF_INET;
  4878. paddr->sin_port = htons(atoi(ports[i]));
  4879. memcpy(&(paddr->sin_addr), ent->h_addr_list[0], ent->h_length);
  4880. cparm.ip_addr[count].ip_addr_len = ent->h_length;
  4881. count++;
  4882. }
  4883. #endif
  4884. if (count == 0)
  4885. return EINVAL;
  4886. cparm.num_ip_addr = count;
  4887. /* At this point we have a validated set of parms in cparm. See
  4888. if we alreay have one that matches. */
  4889. lan = find_matching_lan(&cparm);
  4890. if (lan) {
  4891. *new_con = lan->ipmi;
  4892. return 0;
  4893. }
  4894. ipmi = ipmi_mem_alloc(sizeof(*ipmi));
  4895. if (!ipmi)
  4896. return ENOMEM;
  4897. memset(ipmi, 0, sizeof(*ipmi));
  4898. ipmi->user_data = user_data;
  4899. ipmi->os_hnd = handlers;
  4900. ipmi->con_type = "rmcp";
  4901. ipmi->priv_level = cparm.privilege;
  4902. for (i=0; i<MAX_IPMI_USED_CHANNELS; i++)
  4903. ipmi->ipmb_addr[i] = 0x20; /* Assume this until told otherwise */
  4904. rv = ipmi_con_attr_init(ipmi);
  4905. if (rv)
  4906. goto out_err;
  4907. lan = ipmi_mem_alloc(sizeof(*lan));
  4908. if (!lan) {
  4909. rv = ENOMEM;
  4910. goto out_err;
  4911. }
  4912. memset(lan, 0, sizeof(*lan));
  4913. ipmi->con_data = lan;
  4914. lan->cparm = cparm;
  4915. for (i=0; i<cparm.num_ip_addr; i++) {
  4916. lan->cparm.ip_addr_str[i] = ipmi_strdup(ip_addrs[i]);
  4917. if (!lan->cparm.ip_addr_str[i]) {
  4918. rv = ENOMEM;
  4919. goto out_err;
  4920. }
  4921. lan->cparm.ip_port_str[i] = ipmi_strdup(ports[i]);
  4922. if (!lan->cparm.ip_port_str[i]) {
  4923. rv = ENOMEM;
  4924. goto out_err;
  4925. }
  4926. }
  4927. lan->refcount = 1;
  4928. lan->users = 1;
  4929. lan->ipmi = ipmi;
  4930. for (i=0; i<MAX_IPMI_USED_CHANNELS; i++)
  4931. lan->slave_addr[i] = 0x20; /* Assume this until told otherwise */
  4932. lan->is_active = 1;
  4933. lan->chosen_authtype = IPMI_AUTHTYPE_DEFAULT;
  4934. lan->curr_ip_addr = 0;
  4935. lan->num_sends = 0;
  4936. lan->connected = 0;
  4937. lan->initialized = 0;
  4938. lan->outstanding_msg_count = 0;
  4939. lan->max_outstanding_msg_count = max_outstanding_msg_count;
  4940. lan->wait_q = NULL;
  4941. lan->wait_q_tail = NULL;
  4942. pa = (struct sockaddr_in *)&(lan->cparm.ip_addr[0]);
  4943. lan->fd = find_free_lan_fd(pa->sin_family, lan, &lan->fd_slot);
  4944. if (! lan->fd) {
  4945. rv = errno;
  4946. goto out_err;
  4947. }
  4948. /* Create the locks if they are available. */
  4949. rv = ipmi_create_lock_os_hnd(handlers, &lan->seq_num_lock);
  4950. if (rv)
  4951. goto out_err;
  4952. rv = ipmi_create_lock_os_hnd(handlers, &lan->ip_lock);
  4953. if (rv)
  4954. goto out_err;
  4955. lan->con_change_handlers = locked_list_alloc(handlers);
  4956. if (!lan->con_change_handlers) {
  4957. rv = ENOMEM;
  4958. goto out_err;
  4959. }
  4960. lan->event_handlers = locked_list_alloc(handlers);
  4961. if (!lan->event_handlers) {
  4962. rv = ENOMEM;
  4963. goto out_err;
  4964. }
  4965. lan->ipmb_change_handlers = locked_list_alloc(handlers);
  4966. if (!lan->ipmb_change_handlers) {
  4967. rv = ENOMEM;
  4968. goto out_err;
  4969. }
  4970. rv = ipmi_create_lock_os_hnd(handlers, &lan->con_change_lock);
  4971. if (rv)
  4972. goto out_err;
  4973. lan->lan_stat_list = locked_list_alloc(handlers);
  4974. if (!lan->lan_stat_list) {
  4975. rv = ENOMEM;
  4976. goto out_err;
  4977. }
  4978. ipmi->start_con = lan_start_con;
  4979. ipmi->set_ipmb_addr = lan_set_ipmb_addr;
  4980. ipmi->add_ipmb_addr_handler = lan_add_ipmb_addr_handler;
  4981. ipmi->remove_ipmb_addr_handler = lan_remove_ipmb_addr_handler;
  4982. ipmi->add_con_change_handler = lan_add_con_change_handler;
  4983. ipmi->remove_con_change_handler = lan_remove_con_change_handler;
  4984. ipmi->send_command = lan_send_command;
  4985. ipmi->add_event_handler = lan_add_event_handler;
  4986. ipmi->remove_event_handler = lan_remove_event_handler;
  4987. ipmi->send_response = lan_send_response;
  4988. ipmi->register_for_command = lan_register_for_command;
  4989. ipmi->deregister_for_command = lan_deregister_for_command;
  4990. ipmi->close_connection = lan_close_connection;
  4991. ipmi->close_connection_done = lan_close_connection_done;
  4992. ipmi->handle_async_event = handle_async_event;
  4993. ipmi->get_startup_args = get_startup_args;
  4994. ipmi->use_connection = lan_use_connection;
  4995. ipmi->send_command_option = lan_send_command_option;
  4996. ipmi->get_num_ports = lan_get_num_ports;
  4997. ipmi->get_port_info = lan_get_port_info;
  4998. ipmi->register_stat_handler = lan_register_stat_handler;
  4999. ipmi->unregister_stat_handler = lan_unregister_stat_handler;
  5000. /* Add it to the list of valid IPMIs so it will validate. This
  5001. must be done last, after a point where it cannot fail. */
  5002. lan_add_con(lan);
  5003. *new_con = ipmi;
  5004. return 0;
  5005. out_err:
  5006. cleanup_con(ipmi);
  5007. return rv;
  5008. }
  5009. static void
  5010. snmp_got_match(lan_data_t *lan,
  5011. const ipmi_msg_t *msg,
  5012. const unsigned char *pet_ack)
  5013. {
  5014. ipmi_system_interface_addr_t si;
  5015. ipmi_msg_t ack;
  5016. int dummy_send_ip;
  5017. si.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
  5018. si.channel = 0xf;
  5019. si.lun = 0;
  5020. handle_async_event(lan->ipmi, (ipmi_addr_t *) &si, sizeof(si), msg);
  5021. /* Send the ack directly. */
  5022. ack.netfn = IPMI_SENSOR_EVENT_NETFN;
  5023. ack.cmd = IPMI_PET_ACKNOWLEDGE_CMD;
  5024. ack.data = (unsigned char *) pet_ack;
  5025. ack.data_len = 12;
  5026. lan_send(lan, (ipmi_addr_t *) &si, sizeof(si), &ack, 0, &dummy_send_ip,
  5027. NULL);
  5028. }
  5029. typedef struct lan_do_evt_s
  5030. {
  5031. lan_data_t *lan;
  5032. struct lan_do_evt_s *next;
  5033. } lan_do_evt_t;
  5034. int
  5035. ipmi_lan_handle_external_event(const struct sockaddr *src_addr,
  5036. const ipmi_msg_t *msg,
  5037. const unsigned char *pet_ack)
  5038. {
  5039. lan_link_t *l;
  5040. lan_data_t *lan;
  5041. unsigned int i;
  5042. unsigned int idx;
  5043. lan_do_evt_t *found = NULL;
  5044. lan_do_evt_t *next = NULL;
  5045. idx = hash_lan_addr(src_addr);
  5046. ipmi_lock(lan_list_lock);
  5047. l = lan_ip_list[idx].next;
  5048. /* Note that we call all the connections with the given IP
  5049. address, not just the first one we find. There may be more
  5050. than one. */
  5051. while (l->lan) {
  5052. lan = NULL;
  5053. for (i=0; i<l->lan->cparm.num_ip_addr; i++) {
  5054. if (l->lan->cparm.ip_addr[i].s_ipsock.s_addr.sa_family
  5055. != src_addr->sa_family)
  5056. {
  5057. continue;
  5058. }
  5059. switch (src_addr->sa_family)
  5060. {
  5061. case PF_INET:
  5062. {
  5063. struct sockaddr_in *src, *dst;
  5064. src = (struct sockaddr_in *) src_addr;
  5065. dst = &(l->lan->cparm.ip_addr[i].s_ipsock.s_addr4);
  5066. if (dst->sin_addr.s_addr == src->sin_addr.s_addr) {
  5067. /* We have a match, handle it */
  5068. lan = l->lan;
  5069. lan->refcount++;
  5070. }
  5071. }
  5072. break;
  5073. #ifdef PF_INET6
  5074. case PF_INET6:
  5075. {
  5076. struct sockaddr_in6 *src, *dst;
  5077. src = (struct sockaddr_in6 *) src_addr;
  5078. dst = &(l->lan->cparm.ip_addr[i].s_ipsock.s_addr6);
  5079. if (memcmp(dst->sin6_addr.s6_addr,
  5080. src->sin6_addr.s6_addr,
  5081. sizeof(struct in6_addr))
  5082. == 0)
  5083. {
  5084. /* We have a match, handle it */
  5085. lan = l->lan;
  5086. lan->refcount++;
  5087. }
  5088. }
  5089. break;
  5090. #endif
  5091. }
  5092. if (lan) {
  5093. next = ipmi_mem_alloc(sizeof(*next));
  5094. if (!next)
  5095. /* Can't do anything, just go on. It's not
  5096. fatal, it just delays things. */
  5097. continue;
  5098. next->lan = lan;
  5099. next->next = found;
  5100. found = next;
  5101. }
  5102. }
  5103. l = l->next;
  5104. }
  5105. ipmi_unlock(lan_list_lock);
  5106. while (found) {
  5107. next = found;
  5108. found = found->next;
  5109. snmp_got_match(next->lan, msg, pet_ack);
  5110. lan_put(next->lan->ipmi);
  5111. ipmi_mem_free(next);
  5112. }
  5113. /* Next will be left non-NULL if something was delivered, it will
  5114. be NULL if nothing was delivered. */
  5115. return next != NULL;
  5116. }
  5117. typedef struct lan_args_s
  5118. {
  5119. char *str_addr[2]; /* parms 0, 1 */
  5120. char *str_port[2]; /* parms 2, 3 */
  5121. int num_addr;
  5122. unsigned int authtype; /* parm 4 */
  5123. unsigned int privilege; /* parm 5 */
  5124. int username_set;
  5125. char username[16]; /* parm 6 */
  5126. unsigned int username_len;
  5127. int password_set;
  5128. char password[20]; /* parm 7 */
  5129. unsigned int password_len;
  5130. unsigned int auth_alg; /* parm 8 */
  5131. unsigned int integ_alg; /* parm 9 */
  5132. unsigned int conf_alg; /* parm 10 */
  5133. unsigned int name_lookup_only; /* parm 11 */
  5134. int bmc_key_set;
  5135. char bmc_key[20]; /* parm 12 */
  5136. unsigned int bmc_key_len;
  5137. unsigned int hacks; /* parms 13, 14 */
  5138. unsigned int max_outstanding_msgs;/* parm 15 */
  5139. } lan_args_t;
  5140. static const char *auth_range[] = { "default", "none", "md2", "md5",
  5141. "straight", "oem", "rmcp+", NULL };
  5142. static int auth_vals[] = { IPMI_AUTHTYPE_DEFAULT,
  5143. IPMI_AUTHTYPE_NONE,
  5144. IPMI_AUTHTYPE_MD2,
  5145. IPMI_AUTHTYPE_MD5,
  5146. IPMI_AUTHTYPE_STRAIGHT,
  5147. IPMI_AUTHTYPE_OEM,
  5148. IPMI_AUTHTYPE_RMCP_PLUS };
  5149. static const char *priv_range[] = { "callback", "user", "operator", "admin",
  5150. "oem", NULL };
  5151. static int priv_vals[] = { IPMI_PRIVILEGE_CALLBACK,
  5152. IPMI_PRIVILEGE_USER,
  5153. IPMI_PRIVILEGE_OPERATOR,
  5154. IPMI_PRIVILEGE_ADMIN,
  5155. IPMI_PRIVILEGE_OEM };
  5156. static const char *auth_alg_range[] = { "bmcpick", "rakp_none",
  5157. "rakp_hmac_sha1", "rakp_hmac_md5",
  5158. NULL };
  5159. static int auth_alg_vals[] = { IPMI_LANP_AUTHENTICATION_ALGORITHM_BMCPICK,
  5160. IPMI_LANP_AUTHENTICATION_ALGORITHM_RAKP_NONE,
  5161. IPMI_LANP_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA1,
  5162. IPMI_LANP_AUTHENTICATION_ALGORITHM_RAKP_HMAC_MD5 };
  5163. static const char *integ_alg_range[] = { "bmcpick", "none", "hmac_sha1",
  5164. "hmac_md5", "md5", NULL };
  5165. static int integ_alg_vals[] = { IPMI_LANP_INTEGRITY_ALGORITHM_BMCPICK,
  5166. IPMI_LANP_INTEGRITY_ALGORITHM_NONE,
  5167. IPMI_LANP_INTEGRITY_ALGORITHM_HMAC_SHA1_96,
  5168. IPMI_LANP_INTEGRITY_ALGORITHM_HMAC_MD5_128,
  5169. IPMI_LANP_INTEGRITY_ALGORITHM_MD5_128 };
  5170. static const char *conf_alg_range[] = { "bmcpick", "none", "aes_cbc_128",
  5171. "xrc4_128", "xrc4_40", NULL };
  5172. static int conf_alg_vals[] = { IPMI_LANP_CONFIDENTIALITY_ALGORITHM_BMCPICK,
  5173. IPMI_LANP_CONFIDENTIALITY_ALGORITHM_NONE,
  5174. IPMI_LANP_CONFIDENTIALITY_ALGORITHM_AES_CBC_128,
  5175. IPMI_LANP_CONFIDENTIALITY_ALGORITHM_xRC4_128,
  5176. IPMI_LANP_CONFIDENTIALITY_ALGORITHM_xRC4_40 };
  5177. static struct lan_argnum_info_s
  5178. {
  5179. const char *name;
  5180. const char *type;
  5181. const char *help;
  5182. const char **range;
  5183. const int *values;
  5184. } lan_argnum_info[17] =
  5185. {
  5186. { "Address", "str",
  5187. "*IP name or address of the MC",
  5188. NULL, NULL },
  5189. { "Port", "str",
  5190. "*IP port or port name for the MC",
  5191. NULL, NULL },
  5192. { "Address2", "str",
  5193. "IP name or address of a second connection to the same MC",
  5194. NULL, NULL },
  5195. { "Port2", "str",
  5196. "IP port or portname for a second connection to the same MC",
  5197. NULL, NULL },
  5198. { "Authtype", "enum",
  5199. "Authentication to use for the connection",
  5200. auth_range, auth_vals },
  5201. { "Privilege", "enum",
  5202. "Privilege level to use for the connection",
  5203. priv_range, priv_vals },
  5204. { "Username", "str",
  5205. "The user name to use for the connection",
  5206. NULL, NULL },
  5207. { "Password", "str",
  5208. "!The password to use for the connection",
  5209. NULL, NULL },
  5210. { "Authentication_Algorithm", "enum",
  5211. "Authentication algorithm to use for the connection, for RMCP+ only",
  5212. auth_alg_range, auth_alg_vals },
  5213. { "Integrity_Algorithm", "enum",
  5214. "Integrity algorithm to use for the connection, for RMCP+ only",
  5215. integ_alg_range, integ_alg_vals },
  5216. { "Confidentiality_Algorithm", "enum",
  5217. "Confidentiality algorithm to use for the connection, for RMCP+ only",
  5218. conf_alg_range, conf_alg_vals },
  5219. { "Name_Lookup_Only", "bool",
  5220. "Use only the name, not the privilege, for selecting the password",
  5221. NULL, NULL },
  5222. { "BMC_Key", "str",
  5223. "The key to use for connecting to the BMC, may or may not be required",
  5224. NULL, NULL },
  5225. { "RAKP3_Wrong_RoleM", "bool",
  5226. "Some systems use the wrong RoleM value for RAKP3, a common problem",
  5227. NULL, NULL },
  5228. { "RMCP_Integ_SIK", "bool",
  5229. "The IPMI 2.0 Spec was unclear which integrity key to use",
  5230. NULL, NULL },
  5231. { "Max_Outstanding_Msgs", "int",
  5232. "How many outstanding messages on the connection, range 1-63",
  5233. NULL, NULL },
  5234. { NULL },
  5235. };
  5236. static ipmi_args_t *lan_con_alloc_args(void);
  5237. static void
  5238. lan_free_args(ipmi_args_t *args)
  5239. {
  5240. lan_args_t *largs = _ipmi_args_get_extra_data(args);
  5241. if (largs->str_addr[0])
  5242. ipmi_mem_free(largs->str_addr[0]);
  5243. if (largs->str_addr[1])
  5244. ipmi_mem_free(largs->str_addr[1]);
  5245. if (largs->str_port[0])
  5246. ipmi_mem_free(largs->str_port[0]);
  5247. if (largs->str_port[1])
  5248. ipmi_mem_free(largs->str_port[1]);
  5249. /* paranoia */
  5250. memset(largs->password, 0, sizeof(largs->password));
  5251. memset(largs->bmc_key, 0, sizeof(largs->bmc_key));
  5252. }
  5253. static ipmi_args_t *
  5254. get_startup_args(ipmi_con_t *ipmi)
  5255. {
  5256. ipmi_args_t *args;
  5257. lan_args_t *largs;
  5258. lan_data_t *lan;
  5259. lan_conn_parms_t *cparm;
  5260. args = lan_con_alloc_args();
  5261. if (! args)
  5262. return NULL;
  5263. largs = _ipmi_args_get_extra_data(args);
  5264. lan = (lan_data_t *) ipmi->con_data;
  5265. cparm = &lan->cparm;
  5266. largs->str_addr[0] = ipmi_strdup(cparm->ip_addr_str[0]);
  5267. if (!largs->str_addr[0])
  5268. goto out_err;
  5269. largs->str_port[0] = ipmi_strdup(cparm->ip_port_str[0]);
  5270. if (!largs->str_port[0])
  5271. goto out_err;
  5272. if (cparm->num_ip_addr > 1) {
  5273. largs->str_addr[1] = ipmi_strdup(cparm->ip_addr_str[1]);
  5274. if (!largs->str_addr[1])
  5275. goto out_err;
  5276. largs->str_port[1] = ipmi_strdup(cparm->ip_port_str[1]);
  5277. if (!largs->str_port[1])
  5278. goto out_err;
  5279. }
  5280. largs->num_addr = cparm->num_ip_addr;
  5281. largs->authtype = cparm->authtype;
  5282. largs->privilege = cparm->privilege;
  5283. if (cparm->username_len) {
  5284. largs->username_len = cparm->username_len ;
  5285. memcpy(largs->username, cparm->username, cparm->username_len);
  5286. largs->username_set = 1;
  5287. }
  5288. if (cparm->password_len) {
  5289. largs->password_len = cparm->password_len ;
  5290. memcpy(largs->password, cparm->password, cparm->password_len);
  5291. largs->password_set = 1;
  5292. }
  5293. largs->conf_alg = cparm->conf;
  5294. largs->auth_alg = cparm->auth;
  5295. largs->integ_alg = cparm->integ;
  5296. largs->name_lookup_only = cparm->name_lookup_only;
  5297. largs->hacks = ipmi->hacks;
  5298. if (cparm->bmc_key_len) {
  5299. largs->bmc_key_len = cparm->bmc_key_len ;
  5300. memcpy(largs->bmc_key, cparm->bmc_key, cparm->bmc_key_len);
  5301. largs->bmc_key_set = 1;
  5302. }
  5303. largs->max_outstanding_msgs = lan->max_outstanding_msg_count;
  5304. return args;
  5305. out_err:
  5306. lan_free_args(args);
  5307. return NULL;
  5308. }
  5309. static int
  5310. lan_connect_args(ipmi_args_t *args,
  5311. os_handler_t *handlers,
  5312. void *user_data,
  5313. ipmi_con_t **con)
  5314. {
  5315. lan_args_t *largs = _ipmi_args_get_extra_data(args);
  5316. int i;
  5317. ipmi_lanp_parm_t parms[12];
  5318. int rv;
  5319. i = 0;
  5320. parms[i].parm_id = IPMI_LANP_PARMID_ADDRS;
  5321. parms[i].parm_data = largs->str_addr;
  5322. parms[i].parm_data_len = largs->num_addr;
  5323. i++;
  5324. parms[i].parm_id = IPMI_LANP_PARMID_PORTS;
  5325. parms[i].parm_data = largs->str_port;
  5326. parms[i].parm_data_len = largs->num_addr;
  5327. i++;
  5328. parms[i].parm_id = IPMI_LANP_PARMID_AUTHTYPE;
  5329. parms[i].parm_val = largs->authtype;
  5330. i++;
  5331. parms[i].parm_id = IPMI_LANP_PARMID_PRIVILEGE;
  5332. parms[i].parm_val = largs->privilege;
  5333. i++;
  5334. if (largs->username_set) {
  5335. parms[i].parm_id = IPMI_LANP_PARMID_USERNAME;
  5336. parms[i].parm_data = largs->username;
  5337. parms[i].parm_data_len = largs->username_len;
  5338. i++;
  5339. }
  5340. if (largs->password_set) {
  5341. parms[i].parm_id = IPMI_LANP_PARMID_PASSWORD;
  5342. parms[i].parm_data = largs->password;
  5343. parms[i].parm_data_len = largs->password_len;
  5344. i++;
  5345. }
  5346. parms[i].parm_id = IPMI_LANP_AUTHENTICATION_ALGORITHM;
  5347. parms[i].parm_val = largs->auth_alg;
  5348. i++;
  5349. parms[i].parm_id = IPMI_LANP_INTEGRITY_ALGORITHM;
  5350. parms[i].parm_val = largs->integ_alg;
  5351. i++;
  5352. parms[i].parm_id = IPMI_LANP_CONFIDENTIALITY_ALGORITHM;
  5353. parms[i].parm_val = largs->conf_alg;
  5354. i++;
  5355. parms[i].parm_id = IPMI_LANP_NAME_LOOKUP_ONLY;
  5356. parms[i].parm_val = largs->name_lookup_only;
  5357. i++;
  5358. if (largs->bmc_key_set) {
  5359. parms[i].parm_id = IPMI_LANP_BMC_KEY;
  5360. parms[i].parm_data = largs->bmc_key;
  5361. parms[i].parm_data_len = largs->bmc_key_len;
  5362. i++;
  5363. }
  5364. parms[i].parm_id = IPMI_LANP_MAX_OUTSTANDING_MSG_COUNT;
  5365. parms[i].parm_val = largs->max_outstanding_msgs;
  5366. i++;
  5367. rv = ipmi_lanp_setup_con(parms, i, handlers, user_data, con);
  5368. if (!rv)
  5369. (*con)->hacks = largs->hacks;
  5370. return rv;
  5371. }
  5372. static int
  5373. get_str_val(char **dest, const char *data, int *is_set, unsigned int *len)
  5374. {
  5375. char *rval = NULL;
  5376. if (!dest)
  5377. return 0;
  5378. if (is_set && (! *is_set)) {
  5379. *dest = NULL;
  5380. return 0;
  5381. }
  5382. if (data) {
  5383. if (len) {
  5384. rval = ipmi_mem_alloc(*len+1);
  5385. if (!rval)
  5386. return ENOMEM;
  5387. memcpy(rval, data, *len);
  5388. rval[*len] = '\0';
  5389. } else {
  5390. rval = ipmi_strdup(data);
  5391. if (!rval)
  5392. return ENOMEM;
  5393. }
  5394. *dest = rval;
  5395. } else {
  5396. *dest = NULL;
  5397. }
  5398. return 0;
  5399. }
  5400. static int
  5401. get_enum_val(int argnum, char **dest, int data, const char ***rrange)
  5402. {
  5403. char *rval = NULL;
  5404. const int *values;
  5405. const char **range;
  5406. int i;
  5407. if (rrange)
  5408. *rrange = lan_argnum_info[argnum].range;
  5409. if (!dest)
  5410. return 0;
  5411. values = lan_argnum_info[argnum].values;
  5412. range = lan_argnum_info[argnum].range;
  5413. for (i=0; range[i]; i++) {
  5414. if (values[i] == data) {
  5415. rval = ipmi_strdup(lan_argnum_info[argnum].range[i]);
  5416. if (!rval)
  5417. return ENOMEM;
  5418. *dest = rval;
  5419. return 0;
  5420. }
  5421. }
  5422. return EINVAL;
  5423. }
  5424. static int
  5425. get_bool_val(char **dest, int data, unsigned int bit)
  5426. {
  5427. char *rval = NULL;
  5428. if (!dest)
  5429. return 0;
  5430. if (data & bit)
  5431. rval = ipmi_strdup("true");
  5432. else
  5433. rval = ipmi_strdup("false");
  5434. if (!rval)
  5435. return ENOMEM;
  5436. *dest = rval;
  5437. return 0;
  5438. }
  5439. static int
  5440. get_int_val(char **dest, int data)
  5441. {
  5442. char *rval = NULL;
  5443. int len;
  5444. if (!dest)
  5445. return 0;
  5446. len = snprintf(NULL, 0, "%d", data);
  5447. rval = malloc(len+1);
  5448. if (!rval)
  5449. return ENOMEM;
  5450. snprintf(rval, len+1, "%d", data);
  5451. *dest = rval;
  5452. return 0;
  5453. }
  5454. static const char *
  5455. lan_args_get_type(ipmi_args_t *args)
  5456. {
  5457. return "lan";
  5458. }
  5459. static int
  5460. lan_args_get_val(ipmi_args_t *args,
  5461. unsigned int argnum,
  5462. const char **name,
  5463. const char **type,
  5464. const char **help,
  5465. char **value,
  5466. const char ***range)
  5467. {
  5468. lan_args_t *largs = _ipmi_args_get_extra_data(args);
  5469. int rv;
  5470. switch(argnum) {
  5471. case 0:
  5472. rv = get_str_val(value, largs->str_addr[0], NULL, NULL);
  5473. break;
  5474. case 1:
  5475. rv = get_str_val(value, largs->str_port[0], NULL, NULL);
  5476. break;
  5477. case 2:
  5478. rv = get_str_val(value, largs->str_addr[1], NULL, NULL);
  5479. break;
  5480. case 3:
  5481. rv = get_str_val(value, largs->str_port[1], NULL, NULL);
  5482. break;
  5483. case 4:
  5484. rv = get_enum_val(argnum, value, largs->authtype, range);
  5485. break;
  5486. case 5:
  5487. rv = get_enum_val(argnum, value, largs->privilege, range);
  5488. break;
  5489. case 6:
  5490. rv = get_str_val(value, largs->username, &largs->username_set,
  5491. &largs->username_len);
  5492. break;
  5493. case 7:
  5494. rv = get_str_val(value, largs->password, &largs->password_set,
  5495. &largs->password_len);
  5496. break;
  5497. case 8:
  5498. rv = get_enum_val(argnum, value, largs->auth_alg, range);
  5499. break;
  5500. case 9:
  5501. rv = get_enum_val(argnum, value, largs->integ_alg, range);
  5502. break;
  5503. case 10:
  5504. rv = get_enum_val(argnum, value, largs->conf_alg, range);
  5505. break;
  5506. case 11:
  5507. rv = get_bool_val(value, largs->name_lookup_only, 1);
  5508. break;
  5509. case 12:
  5510. rv = get_str_val(value, largs->bmc_key, &largs->bmc_key_set,
  5511. &largs->bmc_key_len);
  5512. break;
  5513. case 13:
  5514. rv = get_bool_val(value, largs->hacks,
  5515. IPMI_CONN_HACK_RAKP3_WRONG_ROLEM);
  5516. break;
  5517. case 14:
  5518. rv = get_bool_val(value, largs->hacks,
  5519. IPMI_CONN_HACK_RMCPP_INTEG_SIK);
  5520. break;
  5521. case 15:
  5522. rv = get_int_val(value, largs->max_outstanding_msgs);
  5523. break;
  5524. default:
  5525. return E2BIG;
  5526. }
  5527. if (rv)
  5528. return rv;
  5529. if (name)
  5530. *name = lan_argnum_info[argnum].name;
  5531. if (type)
  5532. *type = lan_argnum_info[argnum].type;
  5533. if (help)
  5534. *help = lan_argnum_info[argnum].help;
  5535. return 0;
  5536. }
  5537. static int
  5538. set_str_val(char **dest, const char *value, int null_ok, int *is_set,
  5539. unsigned int *len, unsigned int max_len)
  5540. {
  5541. char *rval;
  5542. if (! value) {
  5543. if (! null_ok)
  5544. return EINVAL;
  5545. *dest = NULL;
  5546. if (is_set)
  5547. *is_set = 0;
  5548. return 0;
  5549. }
  5550. if (len) {
  5551. unsigned int nlen = strlen(value);
  5552. if (nlen > max_len)
  5553. return EINVAL;
  5554. memcpy(*dest, value, nlen);
  5555. *len = nlen;
  5556. } else {
  5557. rval = ipmi_strdup(value);
  5558. if (!rval)
  5559. return ENOMEM;
  5560. if (*dest)
  5561. ipmi_mem_free(*dest);
  5562. *dest = rval;
  5563. }
  5564. if (is_set)
  5565. *is_set = 1;
  5566. return 0;
  5567. }
  5568. static int
  5569. set_enum_val(int argnum, unsigned int *dest, const char *value)
  5570. {
  5571. const char **range;
  5572. int i;
  5573. if (! value)
  5574. return EINVAL;
  5575. range = lan_argnum_info[argnum].range;
  5576. for (i=0; range[i]; i++) {
  5577. if (strcmp(range[i], value) == 0) {
  5578. *dest = lan_argnum_info[argnum].values[i];
  5579. return 0;
  5580. }
  5581. }
  5582. return EINVAL;
  5583. }
  5584. static int
  5585. set_bool_val(unsigned int *dest, const char *value, unsigned int bit)
  5586. {
  5587. if (! value)
  5588. return EINVAL;
  5589. if (strcmp(value, "true") == 0)
  5590. *dest |= bit;
  5591. else if (strcmp(value, "false") == 0)
  5592. *dest &= ~bit;
  5593. else
  5594. return EINVAL;
  5595. return 0;
  5596. }
  5597. static int
  5598. set_uint_val(unsigned int *dest, const char *value)
  5599. {
  5600. int val;
  5601. char *end;
  5602. if (! value)
  5603. return EINVAL;
  5604. if (*value == '\0')
  5605. return EINVAL;
  5606. val = strtoul(value, &end, 0);
  5607. if (*end != '\0')
  5608. return EINVAL;
  5609. *dest = val;
  5610. return 0;
  5611. }
  5612. static int
  5613. lan_args_set_val(ipmi_args_t *args,
  5614. unsigned int argnum,
  5615. const char *name,
  5616. const char *value)
  5617. {
  5618. lan_args_t *largs = _ipmi_args_get_extra_data(args);
  5619. int rv;
  5620. char *sval;
  5621. if (name) {
  5622. int i;
  5623. for (i=0; lan_argnum_info[i].name; i++) {
  5624. if (strcmp(lan_argnum_info[i].name, name) == 0)
  5625. break;
  5626. }
  5627. if (! lan_argnum_info[i].name)
  5628. return EINVAL;
  5629. argnum = i;
  5630. }
  5631. switch (argnum) {
  5632. case 0:
  5633. rv = set_str_val(&(largs->str_addr[0]), value, 0, NULL, NULL, 0);
  5634. if (!rv && (largs->num_addr == 0))
  5635. largs->num_addr = 1;
  5636. break;
  5637. case 1:
  5638. rv = set_str_val(&(largs->str_port[0]), value, 1, NULL, NULL, 0);
  5639. break;
  5640. case 2:
  5641. rv = set_str_val(&(largs->str_addr[1]), value, 1, NULL, NULL, 0);
  5642. if (!rv) {
  5643. if (largs->str_addr[1]) {
  5644. if (largs->num_addr < 2)
  5645. largs->num_addr = 2;
  5646. } else {
  5647. if (largs->str_addr[0])
  5648. largs->num_addr = 1;
  5649. else
  5650. largs->num_addr = 0;
  5651. }
  5652. }
  5653. break;
  5654. case 3:
  5655. rv = set_str_val(&(largs->str_port[1]), value, 1, NULL, NULL, 0);
  5656. break;
  5657. case 4:
  5658. rv = set_enum_val(argnum, &largs->authtype, value);
  5659. break;
  5660. case 5:
  5661. rv = set_enum_val(argnum, &largs->privilege, value);
  5662. break;
  5663. case 6:
  5664. sval = largs->username;
  5665. rv = set_str_val(&sval, value, 1, &largs->username_set,
  5666. &largs->username_len, 16);
  5667. break;
  5668. case 7:
  5669. sval = largs->password;
  5670. rv = set_str_val(&sval, value, 1, &largs->password_set,
  5671. &largs->password_len, 20);
  5672. break;
  5673. case 8:
  5674. rv = set_enum_val(argnum, &largs->auth_alg, value);
  5675. break;
  5676. case 9:
  5677. rv = set_enum_val(argnum, &largs->integ_alg, value);
  5678. break;
  5679. case 10:
  5680. rv = set_enum_val(argnum, &largs->conf_alg, value);
  5681. break;
  5682. case 11:
  5683. rv = set_bool_val(&largs->name_lookup_only, value, 1);
  5684. break;
  5685. case 12:
  5686. sval = largs->bmc_key;
  5687. rv = set_str_val(&sval, value, 1, &largs->bmc_key_set,
  5688. &largs->bmc_key_len, 20);
  5689. break;
  5690. case 13:
  5691. rv = set_bool_val(&largs->hacks, value,
  5692. IPMI_CONN_HACK_RAKP3_WRONG_ROLEM);
  5693. break;
  5694. case 14:
  5695. rv = set_bool_val(&largs->hacks, value,
  5696. IPMI_CONN_HACK_RMCPP_INTEG_SIK);
  5697. break;
  5698. case 15:
  5699. rv = set_uint_val(&largs->max_outstanding_msgs, value);
  5700. break;
  5701. default:
  5702. rv = E2BIG;
  5703. }
  5704. return rv;
  5705. }
  5706. static ipmi_args_t *
  5707. lan_args_copy(ipmi_args_t *args)
  5708. {
  5709. ipmi_args_t *nargs;
  5710. lan_args_t *largs = _ipmi_args_get_extra_data(args);
  5711. lan_args_t *nlargs;
  5712. nargs = lan_con_alloc_args();
  5713. if (!nargs)
  5714. return NULL;
  5715. nlargs = _ipmi_args_get_extra_data(nargs);
  5716. *nlargs = *largs;
  5717. nlargs->str_addr[0] = NULL;
  5718. nlargs->str_addr[1] = NULL;
  5719. nlargs->str_port[0] = NULL;
  5720. nlargs->str_port[1] = NULL;
  5721. nlargs->str_addr[0] = ipmi_strdup(largs->str_addr[0]);
  5722. if (! nlargs->str_addr[0])
  5723. goto out_err;
  5724. nlargs->str_addr[1] = ipmi_strdup(largs->str_addr[1]);
  5725. if (! nlargs->str_addr[1])
  5726. goto out_err;
  5727. nlargs->str_port[0] = ipmi_strdup(largs->str_port[0]);
  5728. if (! nlargs->str_port[0])
  5729. goto out_err;
  5730. nlargs->str_port[1] = ipmi_strdup(largs->str_port[1]);
  5731. if (! nlargs->str_port[1])
  5732. goto out_err;
  5733. return nargs;
  5734. out_err:
  5735. lan_free_args(nargs);
  5736. return NULL;
  5737. }
  5738. static int
  5739. lan_args_validate(ipmi_args_t *args, int *argnum)
  5740. {
  5741. return 1; /* Can't be invalid */
  5742. }
  5743. static void
  5744. lan_args_free_val(ipmi_args_t *args, char *value)
  5745. {
  5746. ipmi_mem_free(value);
  5747. }
  5748. #define CHECK_ARG \
  5749. do { \
  5750. if (*curr_arg >= arg_count) { \
  5751. rv = EINVAL; \
  5752. goto out_err; \
  5753. } \
  5754. } while(0)
  5755. static int
  5756. lan_parse_args(int *curr_arg,
  5757. int arg_count,
  5758. char * const *args,
  5759. ipmi_args_t **iargs)
  5760. {
  5761. int rv;
  5762. ipmi_args_t *p = NULL;
  5763. lan_args_t *largs;
  5764. int i;
  5765. int len;
  5766. CHECK_ARG;
  5767. p = lan_con_alloc_args();
  5768. if (!p)
  5769. return ENOMEM;
  5770. largs = _ipmi_args_get_extra_data(p);
  5771. largs->num_addr = 1;
  5772. while (*curr_arg < arg_count) {
  5773. if (args[*curr_arg][0] != '-') {
  5774. break;
  5775. }
  5776. if (strcmp(args[*curr_arg], "-U") == 0) {
  5777. (*curr_arg)++; CHECK_ARG;
  5778. len = strlen(args[*curr_arg]);
  5779. if (len > 16)
  5780. len = 16;
  5781. memcpy(largs->username, args[*curr_arg], len);
  5782. largs->username_set = 1;
  5783. largs->username_len = len;
  5784. } else if (strcmp(args[*curr_arg], "-P") == 0) {
  5785. (*curr_arg)++; CHECK_ARG;
  5786. len = strlen(args[*curr_arg]);
  5787. if (len > 20)
  5788. len = 20;
  5789. memcpy(largs->password, args[*curr_arg], len);
  5790. largs->password_set = 1;
  5791. largs->password_len = len;
  5792. } else if (strcmp(args[*curr_arg], "-H") == 0) {
  5793. (*curr_arg)++; CHECK_ARG;
  5794. if (strcmp(args[*curr_arg], "intelplus") == 0)
  5795. largs->hacks |= IPMI_CONN_HACK_RAKP3_WRONG_ROLEM;
  5796. else if (strcmp(args[*curr_arg], "rakp3_wrong_rolem") == 0)
  5797. largs->hacks |= IPMI_CONN_HACK_RAKP3_WRONG_ROLEM;
  5798. else if (strcmp(args[*curr_arg], "rmcpp_integ_sik") == 0)
  5799. largs->hacks |= IPMI_CONN_HACK_RMCPP_INTEG_SIK;
  5800. /* Ignore unknown hacks. */
  5801. } else if (strcmp(args[*curr_arg], "-s") == 0) {
  5802. largs->num_addr = 2;
  5803. } else if (strcmp(args[*curr_arg], "-A") == 0) {
  5804. (*curr_arg)++; CHECK_ARG;
  5805. if (strcmp(args[*curr_arg], "none") == 0) {
  5806. largs->authtype = IPMI_AUTHTYPE_NONE;
  5807. } else if (strcmp(args[*curr_arg], "md2") == 0) {
  5808. largs->authtype = IPMI_AUTHTYPE_MD2;
  5809. } else if (strcmp(args[*curr_arg], "md5") == 0) {
  5810. largs->authtype = IPMI_AUTHTYPE_MD5;
  5811. } else if (strcmp(args[*curr_arg], "straight") == 0) {
  5812. largs->authtype = IPMI_AUTHTYPE_STRAIGHT;
  5813. } else if (strcmp(args[*curr_arg], "rmcp+") == 0) {
  5814. largs->authtype = IPMI_AUTHTYPE_RMCP_PLUS;
  5815. } else {
  5816. rv = EINVAL;
  5817. goto out_err;
  5818. }
  5819. } else if (strcmp(args[*curr_arg], "-L") == 0) {
  5820. (*curr_arg)++; CHECK_ARG;
  5821. if (strcmp(args[*curr_arg], "callback") == 0) {
  5822. largs->privilege = IPMI_PRIVILEGE_CALLBACK;
  5823. } else if (strcmp(args[*curr_arg], "user") == 0) {
  5824. largs->privilege = IPMI_PRIVILEGE_USER;
  5825. } else if (strcmp(args[*curr_arg], "operator") == 0) {
  5826. largs->privilege = IPMI_PRIVILEGE_OPERATOR;
  5827. } else if (strcmp(args[*curr_arg], "admin") == 0) {
  5828. largs->privilege = IPMI_PRIVILEGE_ADMIN;
  5829. } else if (strcmp(args[*curr_arg], "oem") == 0) {
  5830. largs->privilege = IPMI_PRIVILEGE_OEM;
  5831. } else {
  5832. rv = EINVAL;
  5833. goto out_err;
  5834. }
  5835. } else if (strcmp(args[*curr_arg], "-p") == 0) {
  5836. (*curr_arg)++; CHECK_ARG;
  5837. largs->str_port[0] = ipmi_strdup(args[*curr_arg]);
  5838. if (largs->str_port[0] == NULL) {
  5839. rv = ENOMEM;
  5840. goto out_err;
  5841. }
  5842. } else if (strcmp(args[*curr_arg], "-p2") == 0) {
  5843. (*curr_arg)++; CHECK_ARG;
  5844. largs->str_port[1] = ipmi_strdup(args[*curr_arg]);
  5845. if (largs->str_port[1] == NULL) {
  5846. rv = ENOMEM;
  5847. goto out_err;
  5848. }
  5849. } else if (strcmp(args[*curr_arg], "-Ra") == 0) {
  5850. (*curr_arg)++; CHECK_ARG;
  5851. if (strcmp(args[*curr_arg], "bmcpick") == 0) {
  5852. largs->auth_alg = IPMI_LANP_AUTHENTICATION_ALGORITHM_BMCPICK;
  5853. } else if (strcmp(args[*curr_arg], "rakp_none") == 0) {
  5854. largs->auth_alg = IPMI_LANP_AUTHENTICATION_ALGORITHM_RAKP_NONE;
  5855. } else if (strcmp(args[*curr_arg], "rakp_hmac_sha1") == 0) {
  5856. largs->auth_alg = IPMI_LANP_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA1;
  5857. } else if (strcmp(args[*curr_arg], "rakp_hmac_md5") == 0) {
  5858. largs->auth_alg = IPMI_LANP_AUTHENTICATION_ALGORITHM_RAKP_HMAC_MD5;
  5859. } else {
  5860. rv = EINVAL;
  5861. goto out_err;
  5862. }
  5863. } else if (strcmp(args[*curr_arg], "-Ri") == 0) {
  5864. (*curr_arg)++; CHECK_ARG;
  5865. if (strcmp(args[*curr_arg], "bmcpick") == 0) {
  5866. largs->integ_alg = IPMI_LANP_INTEGRITY_ALGORITHM_BMCPICK;
  5867. } else if (strcmp(args[*curr_arg], "none") == 0) {
  5868. largs->integ_alg = IPMI_LANP_INTEGRITY_ALGORITHM_NONE;
  5869. } else if (strcmp(args[*curr_arg], "hmac_sha1") == 0) {
  5870. largs->integ_alg = IPMI_LANP_INTEGRITY_ALGORITHM_HMAC_SHA1_96;
  5871. } else if (strcmp(args[*curr_arg], "hmac_md5") == 0) {
  5872. largs->integ_alg = IPMI_LANP_INTEGRITY_ALGORITHM_HMAC_MD5_128;
  5873. } else if (strcmp(args[*curr_arg], "md5") == 0) {
  5874. largs->integ_alg = IPMI_LANP_INTEGRITY_ALGORITHM_MD5_128;
  5875. } else {
  5876. rv = EINVAL;
  5877. goto out_err;
  5878. }
  5879. } else if (strcmp(args[*curr_arg], "-Rc") == 0) {
  5880. (*curr_arg)++; CHECK_ARG;
  5881. if (strcmp(args[*curr_arg], "bmcpick") == 0) {
  5882. largs->conf_alg = IPMI_LANP_CONFIDENTIALITY_ALGORITHM_BMCPICK;
  5883. } else if (strcmp(args[*curr_arg], "none") == 0) {
  5884. largs->conf_alg = IPMI_LANP_CONFIDENTIALITY_ALGORITHM_NONE;
  5885. } else if (strcmp(args[*curr_arg], "aes_cbc_128") == 0) {
  5886. largs->conf_alg = IPMI_LANP_CONFIDENTIALITY_ALGORITHM_AES_CBC_128;
  5887. } else if (strcmp(args[*curr_arg], "xrc4_128") == 0) {
  5888. largs->conf_alg = IPMI_LANP_CONFIDENTIALITY_ALGORITHM_xRC4_128;
  5889. } else if (strcmp(args[*curr_arg], "xrc4_40") == 0) {
  5890. largs->conf_alg = IPMI_LANP_CONFIDENTIALITY_ALGORITHM_xRC4_40;
  5891. } else {
  5892. rv = EINVAL;
  5893. goto out_err;
  5894. }
  5895. } else if (strcmp(args[*curr_arg], "-Rl") == 0) {
  5896. largs->name_lookup_only = 0;
  5897. } else if (strcmp(args[*curr_arg], "-Rk") == 0) {
  5898. (*curr_arg)++; CHECK_ARG;
  5899. len = strlen(args[*curr_arg]);
  5900. if (len > 20)
  5901. len = 20;
  5902. memcpy(largs->bmc_key, args[*curr_arg], len);
  5903. largs->bmc_key_set = 1;
  5904. largs->bmc_key_len = len;
  5905. } else if (strcmp(args[*curr_arg], "-M") == 0) {
  5906. char *end;
  5907. int val;
  5908. (*curr_arg)++; CHECK_ARG;
  5909. if (args[*curr_arg][0] == '\0') {
  5910. rv = EINVAL;
  5911. goto out_err;
  5912. }
  5913. val = strtol(args[*curr_arg], &end, 0);
  5914. if (*end != '\0') {
  5915. rv = EINVAL;
  5916. goto out_err;
  5917. }
  5918. largs->max_outstanding_msgs = val;
  5919. }
  5920. (*curr_arg)++;
  5921. }
  5922. for (i=0; i<largs->num_addr; i++) {
  5923. CHECK_ARG;
  5924. largs->str_addr[i] = ipmi_strdup(args[*curr_arg]);
  5925. if (largs->str_addr[i] == NULL) {
  5926. rv = ENOMEM;
  5927. goto out_err;
  5928. }
  5929. (*curr_arg)++;
  5930. if (! largs->str_port[i]) {
  5931. largs->str_port[i] = ipmi_strdup("623");
  5932. if (largs->str_port[i] == NULL) {
  5933. rv = ENOMEM;
  5934. goto out_err;
  5935. }
  5936. }
  5937. }
  5938. *iargs = p;
  5939. return 0;
  5940. out_err:
  5941. if (p)
  5942. ipmi_free_args(p);
  5943. return rv;
  5944. }
  5945. static const char *
  5946. lan_parse_help(void)
  5947. {
  5948. return
  5949. "\n"
  5950. " lan [-U <username>] [-P <password>] [-p[2] port] [-A <authtype>]\n"
  5951. " [-L <privilege>] [-s] [-Ra <auth alg>] [-Ri <integ alg>]\n"
  5952. " [-Rc <conf algo>] [-Rl] [-Rk <bmc key>] [-H <hackname>]\n"
  5953. " [-M <max outstanding msgs>] <host1> [<host2>]\n"
  5954. "If -s is supplied, then two host names are taken (the second port\n"
  5955. "may be specified with -p2). Otherwise, only one hostname is\n"
  5956. "taken. The defaults are an empty username and password (anonymous),\n"
  5957. "port 623, admin privilege, and authtype defaulting to the most\n"
  5958. "secure one available.\n"
  5959. "privilege is one of: callback, user, operator, admin, or oem. These\n"
  5960. "select the specific commands that are available to the connection.\n"
  5961. "Higher privileges (ones further to the right in the above list) have\n"
  5962. "more commands available to them.\n"
  5963. "authtype is one of the following: rmcp+, md5, md2, straight, or none.\n"
  5964. "Setting this to anything but rmcp+ forces normal rmcp\n"
  5965. "authentication. By default the most secure method available is\n"
  5966. "chosen, in the order given above.\n"
  5967. "For RMCP+ connections, the authentication algorithms supported (-Ra)\n"
  5968. "are: bmcpick, rakp_none, rakp_hmac_sha1, and rakp_hmac_md5. The\n"
  5969. "integrity algorithms (-Ri) supported are: bmcpick, none, hmac_sha1,\n"
  5970. "hmac_md5, and md5. The confidentiality algorithms (-Rc) are: bmcpick,\n"
  5971. "aes_cbc_128, xrc4_128, and xrc_40. The defaults are\n"
  5972. "rackp_hmac_sha1, hmac_sha1, and aes_cb_128. -Rl turns on lookup up\n"
  5973. "names by the name and the privilege level (allowing the same name with\n"
  5974. "different privileges and different passwords), the default is straight\n"
  5975. "name lookup. -Rk sets the BMC key, needed if the system does two-key\n"
  5976. "lookups. The -M option sets the maximum outstanding messages.\n"
  5977. "The default is 2, ranges 1-63.\n"
  5978. "The -H option enables certain hacks for broken platforms. This may\n"
  5979. "be listed multiple times to enable multiple hacks. The currently\n"
  5980. "available hacks are:\n"
  5981. " intelplus - For Intel platforms that have broken RMCP+.\n"
  5982. " rakp3_wrong_rolem - For systems that truncate role(m) in the RAKP3"
  5983. " msg.\n"
  5984. " rmcpp_integ_sik - For systems that use SIK instead of K(1) for"
  5985. " integrity.";
  5986. }
  5987. static ipmi_args_t *
  5988. lan_con_alloc_args(void)
  5989. {
  5990. ipmi_args_t *args;
  5991. lan_args_t *largs;
  5992. args = _ipmi_args_alloc(lan_free_args, lan_connect_args,
  5993. lan_args_get_val, lan_args_set_val,
  5994. lan_args_copy, lan_args_validate,
  5995. lan_args_free_val, lan_args_get_type,
  5996. sizeof(lan_args_t));
  5997. if (!args)
  5998. return NULL;
  5999. largs = _ipmi_args_get_extra_data(args);
  6000. /* Set defaults */
  6001. largs->authtype = IPMI_AUTHTYPE_DEFAULT;
  6002. largs->privilege = IPMI_PRIVILEGE_ADMIN;
  6003. largs->conf_alg = most_secure_lanp_conf();
  6004. largs->integ_alg = most_secure_lanp_integ();
  6005. largs->auth_alg = most_secure_lanp_auth();
  6006. largs->name_lookup_only = 1;
  6007. largs->max_outstanding_msgs = DEFAULT_MAX_OUTSTANDING_MSG_COUNT;
  6008. /* largs->hacks = IPMI_CONN_HACK_RAKP3_WRONG_ROLEM; */
  6009. return args;
  6010. }
  6011. static ipmi_con_setup_t *lan_setup;
  6012. int
  6013. _ipmi_lan_init(os_handler_t *os_hnd)
  6014. {
  6015. int rv;
  6016. int i;
  6017. rv = ipmi_create_global_lock(&lan_list_lock);
  6018. if (rv)
  6019. return rv;
  6020. rv = ipmi_create_global_lock(&fd_list_lock);
  6021. if (rv)
  6022. return rv;
  6023. memset(&fd_list, 0, sizeof(fd_list));
  6024. fd_list.next = &fd_list;
  6025. fd_list.prev = &fd_list;
  6026. fd_list.cons_in_use = MAX_CONS_PER_FD;
  6027. #ifdef PF_INET6
  6028. rv = ipmi_create_global_lock(&fd6_list_lock);
  6029. if (rv)
  6030. return rv;
  6031. memset(&fd6_list, 0, sizeof(fd6_list));
  6032. fd6_list.next = &fd6_list;
  6033. fd6_list.prev = &fd6_list;
  6034. fd6_list.cons_in_use = MAX_CONS_PER_FD;
  6035. #endif
  6036. for (i=0; i<LAN_HASH_SIZE; i++) {
  6037. lan_list[i].next = &(lan_list[i]);
  6038. lan_list[i].prev = &(lan_list[i]);
  6039. lan_list[i].lan = NULL;
  6040. lan_ip_list[i].next = &(lan_ip_list[i]);
  6041. lan_ip_list[i].prev = &(lan_ip_list[i]);
  6042. lan_ip_list[i].lan = NULL;
  6043. }
  6044. rv = ipmi_create_global_lock(&lan_payload_lock);
  6045. if (rv)
  6046. return rv;
  6047. rv = ipmi_create_global_lock(&lan_auth_lock);
  6048. if (rv)
  6049. return rv;
  6050. lan_setup = _ipmi_alloc_con_setup(lan_parse_args, lan_parse_help,
  6051. lan_con_alloc_args);
  6052. if (! lan_setup)
  6053. return ENOMEM;
  6054. rv = _ipmi_register_con_type("lan", lan_setup);
  6055. if (rv)
  6056. return rv;
  6057. lan_os_hnd = os_hnd;
  6058. return 0;
  6059. }
  6060. void
  6061. _ipmi_lan_shutdown(void)
  6062. {
  6063. _ipmi_unregister_con_type("lan", lan_setup);
  6064. _ipmi_free_con_setup(lan_setup);
  6065. lan_setup = NULL;
  6066. if (lan_list_lock) {
  6067. ipmi_destroy_lock(lan_list_lock);
  6068. lan_list_lock = NULL;
  6069. }
  6070. if (lan_payload_lock) {
  6071. ipmi_destroy_lock(lan_payload_lock);
  6072. lan_payload_lock = NULL;
  6073. }
  6074. while (oem_payload_list) {
  6075. payload_entry_t *e = oem_payload_list;
  6076. oem_payload_list = e->next;
  6077. ipmi_mem_free(e);
  6078. }
  6079. if (lan_auth_lock) {
  6080. ipmi_destroy_lock(lan_auth_lock);
  6081. lan_auth_lock = NULL;
  6082. }
  6083. while (oem_auth_list) {
  6084. auth_entry_t *e = oem_auth_list;
  6085. oem_auth_list = e->next;
  6086. ipmi_mem_free(e);
  6087. }
  6088. while (oem_conf_list) {
  6089. conf_entry_t *e = oem_conf_list;
  6090. oem_conf_list = e->next;
  6091. ipmi_mem_free(e);
  6092. }
  6093. while (oem_integ_list) {
  6094. integ_entry_t *e = oem_integ_list;
  6095. oem_integ_list = e->next;
  6096. ipmi_mem_free(e);
  6097. }
  6098. if (fd_list_lock) {
  6099. ipmi_destroy_lock(fd_list_lock);
  6100. fd_list_lock = NULL;
  6101. }
  6102. while (fd_list.next != &fd_list) {
  6103. lan_fd_t *e = fd_list.next;
  6104. e->next->prev = e->prev;
  6105. e->prev->next = e->next;
  6106. lan_os_hnd->remove_fd_to_wait_for(lan_os_hnd, e->fd_wait_id);
  6107. close(e->fd);
  6108. ipmi_destroy_lock(e->con_lock);
  6109. ipmi_mem_free(e);
  6110. }
  6111. while (fd_free_list) {
  6112. lan_fd_t *e = fd_free_list;
  6113. fd_free_list = e->next;
  6114. ipmi_destroy_lock(e->con_lock);
  6115. ipmi_mem_free(e);
  6116. }
  6117. #ifdef PF_INET6
  6118. if (fd6_list_lock) {
  6119. ipmi_destroy_lock(fd6_list_lock);
  6120. fd6_list_lock = NULL;
  6121. }
  6122. while (fd6_list.next != &fd6_list) {
  6123. lan_fd_t *e = fd6_list.next;
  6124. e->next->prev = e->prev;
  6125. e->prev->next = e->next;
  6126. lan_os_hnd->remove_fd_to_wait_for(lan_os_hnd, e->fd_wait_id);
  6127. close(e->fd);
  6128. ipmi_destroy_lock(e->con_lock);
  6129. ipmi_mem_free(e);
  6130. }
  6131. while (fd6_free_list) {
  6132. lan_fd_t *e = fd6_free_list;
  6133. fd6_free_list = e->next;
  6134. ipmi_destroy_lock(e->con_lock);
  6135. ipmi_mem_free(e);
  6136. }
  6137. #endif
  6138. lan_os_hnd = NULL;
  6139. }