ipmi_lan.c revision 81d9f076db88c1f40c85831ce1ebb444a209c5a8
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock * CDDL HEADER START
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock * The contents of this file are subject to the terms of the
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock * Common Development and Distribution License (the "License").
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock * You may not use this file except in compliance with the License.
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock * See the License for the specific language governing permissions
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock * and limitations under the License.
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock * When distributing Covered Code, include this CDDL HEADER in each
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock * If applicable, add the following below this CDDL HEADER, with the
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock * fields enclosed by brackets "[]" replaced with your own identifying
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock * information: Portions Copyright [yyyy] [name of copyright owner]
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock * CDDL HEADER END
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock * Use is subject to license terms.
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstontypedef struct ipmi_rs {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonstatic ipmi_rs_t *ipmi_lan_poll_recv(ipmi_handle_t *);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstontypedef struct ipmi_rq_entry {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * LAN transport-specific data
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstontypedef struct ipmi_lan {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston char il_authcode[IPMI_AUTHCODE_BUF_SIZE + 1];
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * Calculate and returns IPMI checksum
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * Checksum algorithm is described in Section 13.8
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * d: buffer to check
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * s: position in buffer to start checksum from
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston for (; s > 0; s--, d++)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonipmi_req_add_entry(ipmi_handle_t *ihp, ipmi_cmd_t *req)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if ((e = ipmi_zalloc(ihp, sizeof (ipmi_rq_entry_t))) == NULL)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) memcpy(&e->ire_req, req, sizeof (ipmi_cmd_t));
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_list_append(&ipmi_req_entries->ire_list, e);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonipmi_req_lookup_entry(ipmi_handle_t *ihp, uint8_t seq, uint8_t cmd)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston for (e = ipmi_list_next(&ipmi_req_entries->ire_list); e != NULL;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (e->ire_rq_seq == seq && e->ire_req.ic_cmd == cmd)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonipmi_req_remove_entry(ipmi_handle_t *ihp, uint8_t seq, uint8_t cmd)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_list_delete(&ipmi_req_entries->ire_list, e);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston while ((e = ipmi_list_next(&ipmi_req_entries->ire_list)) != NULL) {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_list_delete(&ipmi_req_entries->ire_list, e);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if ((fd = open("/dev/urandom", O_RDONLY)) < 0)
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock return (-1);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonipmi_lan_send_packet(ipmi_handle_t *ihp, uint8_t *data, int dlen)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_lan_t *ilp = (ipmi_lan_t *)ihp->ih_tdata;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_lan_t *ilp = (ipmi_lan_t *)ihp->ih_tdata;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ret = select(ilp->il_sd + 1, &read_set, NULL, &err_set, &tmout);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (ret < 0 || FD_ISSET(ilp->il_sd, &err_set) ||
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * The first read may return ECONNREFUSED because the rmcp ping
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * packet--sent to UDP port 623--will be processed by both the
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * BMC and the OS.
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * The problem with this is that the ECONNREFUSED takes
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * priority over any other received datagram; that means that
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * the Connection Refused shows up _before_ the response packet,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * regardless of the order they were sent out. (unless the
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * response is read before the connection refused is returned)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ret = recv(ilp->il_sd, &rsp.ir_data, IPMI_BUF_SIZE, 0);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ret = select(ilp->il_sd + 1, &read_set, NULL, &err_set, &tmout);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ret = recv(ilp->il_sd, &rsp.ir_data, IPMI_BUF_SIZE, 0);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * ASF/RMCP Pong Message
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * See section 13.2.4
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * parse response RMCP "pong" packet
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * return -1 if ping response not received
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * returns 0 if IPMI is NOT supported
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * returns 1 if IPMI is supported
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonipmi_handle_pong(ipmi_handle_t *ihp, ipmi_rs_t *rsp)
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock return (-1);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /*LINTED: E_BAD_PTR_CAST_ALIGN*/
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return ((pong->rp_sup_entities & 0x80) ? 1 : 0);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * Build and send RMCP presence ping message
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston int rv, dlen = sizeof (rmcp_ping) + sizeof (asf_ping);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) memset(&rmcp_ping, 0, sizeof (rmcp_ping));
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) memset(&asf_ping, 0, sizeof (asf_ping));
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if ((data = ipmi_zalloc(ihp, dlen)) == NULL)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) memcpy(data, &rmcp_ping, sizeof (rmcp_ping));
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) memcpy(data + sizeof (rmcp_ping), &asf_ping, sizeof (asf_ping));
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return (ipmi_set_error(ihp, EIPMI_LAN_PING_FAILED, NULL));
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return (ipmi_set_error(ihp, EIPMI_LAN_PING_FAILED, NULL));
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_lan_t *ilp = (ipmi_lan_t *)ihp->ih_tdata;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /* parse response headers */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /* ping response packet */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /* handled by rest of function */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /* Invalid RMCP class */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (ilp->il_send_authcode && (rsp_authtype || ilp->il_authtype))
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) memcpy(&rsp->ir_ihdr, (void *)(rsp->ir_data + off),
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rsp->ir_ihdr.imh_seq = rsp->ir_ihdr.imh_seq >> 2;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston entry = ipmi_req_lookup_entry(ihp, rsp->ir_ihdr.imh_seq,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_req_remove_entry(ihp, rsp->ir_ihdr.imh_seq,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /* shift response data to start of array */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) memmove(rsp->ir_data, rsp->ir_data + off, rsp->ir_dlen);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) memset(rsp->ir_data + rsp->ir_dlen, 0,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * IPMI LAN Request Message Format
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * See section 13.8
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * +---------------------+
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * | rmcp_hdr_t | 4 bytes
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * +---------------------+
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * | v15_session_hdr_t | 9 bytes
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * +---------------------+
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * | [authcode] | 16 bytes (if AUTHTYPE != none)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * +---------------------+
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * | msg length | 1 byte
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * +---------------------+
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * | ipmi_msg_hdr_t | 6 bytes
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * +---------------------+
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * | [msg data] | variable
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * +---------------------+
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * | msg data checksum | 1 byte
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * +---------------------+
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonipmi_lan_build_cmd(ipmi_handle_t *ihp, ipmi_cmd_t *req)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_lan_t *ilp = (ipmi_lan_t *)ihp->ih_tdata;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston static int curr_seq = 0;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if ((entry = ipmi_req_add_entry(ihp, req)) == NULL)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (ilp->il_send_authcode && ilp->il_authtype)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /* ipmi_errno set */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /* RMCP header */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) memset(&rmcp_hdr, 0, sizeof (rmcp_hdr));
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) memcpy(msg, &rmcp_hdr, sizeof (rmcp_hdr));
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /* IPMI session header */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) memset(&session_hdr, 0, sizeof (session_hdr));
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /* hardcode passwd authentication */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) memcpy(&session_hdr.sh_seq, &ilp->il_in_seq, sizeof (uint32_t));
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) memcpy(&session_hdr.sh_id, &ilp->il_session_id,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) memcpy(msg + off, &session_hdr, sizeof (session_hdr));
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /* IPMI session authcode */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (ilp->il_send_authcode && ilp->il_authtype) {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) memcpy(msg + off, ilp->il_authcode, 16);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /* message length */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /* IPMI message header */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) memset(&msg_hdr, 0, sizeof (msg_hdr));
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston msg_hdr.imh_csum = ipmi_csum(msg + cs, tmp);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) memcpy(msg + off, &msg_hdr, sizeof (msg_hdr));
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /* message data */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) memcpy(msg + off, req->ic_data, req->ic_dlen);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /* message data checksum */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonipmi_lan_send(void *data, ipmi_cmd_t *cmd, ipmi_cmd_t *response,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if ((entry = ipmi_lan_build_cmd(ilp->il_ihp, cmd)) == NULL)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (ipmi_lan_send_packet(ilp->il_ihp, entry->ire_msg_data,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if ((rsp = ipmi_lan_poll_recv(ilp->il_ihp)) != NULL)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_req_remove_entry(ilp->il_ihp, entry->ire_rq_seq,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston response->ic_netfn = rsp->ir_ihdr.imh_netfn;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * IPMI Get Session Challenge Command
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * Copies the returned session ID and 16-byte challenge string to the supplied
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * See section 22.16
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonipmi_get_session_challenge_cmd(ipmi_handle_t *ihp, uint32_t *session_id,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_lan_t *ilp = (ipmi_lan_t *)ihp->ih_tdata;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) memcpy(msg_data + 1, ilp->il_user, 16);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston cmd.ic_cmd = IPMI_CMD_GET_SESSION_CHALLENGE;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (ipmi_lan_send(ilp, &cmd, &resp, &ccode) != 0 || ccode)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return (ipmi_set_error(ihp, EIPMI_LAN_CHALLENGE, NULL));
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) memcpy(challenge, (uint8_t *)resp.ic_data + 4, 16);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * IPMI Activate Session Command
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * See section 22.17
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonipmi_activate_session_cmd(ipmi_handle_t *ihp)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_lan_t *ilp = (ipmi_lan_t *)ihp->ih_tdata;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) memcpy(msg_data + 2, ilp->il_challenge, 16);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /* setup initial outbound sequence number */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (ipmi_lan_send(ilp, &cmd, &resp, &ccode) != 0 || ccode) {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return (ipmi_set_error(ihp, EIPMI_LAN_SESSION, NULL));
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) memcpy(&ilp->il_session_id, resp_data + 1, 4);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ilp->il_in_seq = resp_data[8] << 24 | resp_data[7] << 16 |
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * See section 22.18
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * returns privilege level or -1 on error
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonipmi_set_session_privlvl_cmd(ipmi_handle_t *ihp, uint8_t privlvl)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return (ipmi_set_error(ihp, EIPMI_BADPARAM, NULL));
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (ipmi_lan_send(ihp->ih_tdata, &cmd, &resp, &ccode) != 0)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ret = ipmi_set_error(ihp, EIPMI_LAN_SETPRIV, NULL);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * See section 22.19
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_lan_t *ilp = (ipmi_lan_t *)ihp->ih_tdata;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) memcpy(&msg_data, &ilp->il_session_id, 4);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (ipmi_lan_send(ilp, &cmd, &resp, &ccode) != 0)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * IPMI LAN Session Activation
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * See section 13.14
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * 1. send "RMCP Presence Ping" message, response message will
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * indicate whether the platform supports IPMI
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * 2. send "Get Channel Authentication Capabilities" command
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * with AUTHTYPE = none, response packet will contain information
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * about supported challenge/response authentication types
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * 3. send "Get Session Challenge" command with AUTHTYPE = none
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * and indicate the authentication type in the message, response
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * packet will contain challenge string and temporary session ID.
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * 4. send "Activate Session" command, authenticated with AUTHTYPE
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * sent in previous message. Also sends the initial value for
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * the outbound sequence number for BMC.
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * 5. BMC returns response confirming session activation and
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * session ID for this session and initial inbound sequence.
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonipmi_lan_activate_session(ipmi_handle_t *ihp)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_lan_t *ilp = (ipmi_lan_t *)ihp->ih_tdata;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if ((ac = ipmi_get_channel_auth_caps(ihp, IPMI_LAN_CHANNEL_E,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * For the sake of simplicity, we're just supporting basic password
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * authentication. If this authentication type is not supported then
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * we'll bail here.
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (!(ac->cap_authtype & IPMI_SESSION_AUTHTYPE_PASSWORD)) {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return (ipmi_set_error(ihp, EIPMI_LAN_PASSWD_NOTSUP, NULL));
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (ipmi_get_session_challenge_cmd(ihp, &ilp->il_session_id,
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock return (-1);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (ipmi_set_session_privlvl_cmd(ihp, ilp->il_privlvl) != 0)
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock return (-1);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonipmi_lan_open(ipmi_handle_t *ihp, nvlist_t *params)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if ((ilp = ipmi_zalloc(ihp, sizeof (ipmi_lan_t))) == NULL) {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /* ipmi errno set */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * Parse the parameters passed in the params nvlist. The following
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * parameters are required
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * IPMI_LAN_HOST, IPMI_LAN_USER and IPMI_LAN_PASSWD
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * If any of these were not specified then we abort
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (nvlist_lookup_string(params, IPMI_LAN_HOST, &hostname) ||
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston nvlist_lookup_string(params, IPMI_LAN_USER, &user) ||
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston nvlist_lookup_string(params, IPMI_LAN_PASSWD, &authcode)) {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) ipmi_set_error(ihp, EIPMI_BADPARAM, NULL);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) strncpy(ilp->il_host, hostname, MAXHOSTNAMELEN);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) strncpy(ilp->il_authcode, authcode, 16);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * IPMI_LAN_PORT is an optional parameter and defaults to port 623
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * IPMI_LAN_PRIVLVL is also optional and defaults to admin
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * IPMI_LAN_TIMEOUT is optional and will default to 3 seconds
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * IPMI_LAN_NUM_RETIES is optional and will default to 5
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (nvlist_lookup_uint16(params, IPMI_LAN_PORT, &ilp->il_port))
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (nvlist_lookup_uint8(params, IPMI_LAN_PRIVLVL, &ilp->il_privlvl))
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (nvlist_lookup_uint32(params, IPMI_LAN_TIMEOUT, &ilp->il_timeout))
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (nvlist_lookup_uint8(params, IPMI_LAN_NUM_RETRIES,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ilp->il_num_retries = DEF_IPMI_LAN_NUM_RETRIES;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ilp->il_authtype = IPMI_SESSION_AUTHTYPE_PASSWORD;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * Open up and connect a UDP socket between us and the service
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ilp->il_addr.sin_port = htons(ilp->il_port);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rc = inet_pton(AF_INET, (const char *)ilp->il_host,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if ((host = gethostbyname((const char *)ilp->il_host))
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) ipmi_set_error(ihp, EIPMI_LAN_OPEN_FAILED, NULL);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) memcpy(&ilp->il_addr.sin_addr, host->h_addr,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if ((ilp->il_sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) ipmi_set_error(ihp, EIPMI_LAN_OPEN_FAILED, NULL);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (connect(ilp->il_sd, (struct sockaddr *)&ilp->il_addr,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston sizeof (struct sockaddr_in)) < 0) {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) ipmi_set_error(ihp, EIPMI_LAN_OPEN_FAILED, NULL);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if ((ipmi_req_entries = ipmi_zalloc(ihp, sizeof (ipmi_rq_entry_t)))
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * Finally we start up the IPMI LAN session