283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock/*
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock * CDDL HEADER START
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock *
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 *
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock * or http://www.opensolaris.org/os/licensing.
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock * See the License for the specific language governing permissions
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock * and limitations under the License.
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock *
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 *
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock * CDDL HEADER END
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock */
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock/*
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock * Use is subject to license terms.
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock */
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston#include <stdlib.h>
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston#include <stdio.h>
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston#include <assert.h>
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston#include <inttypes.h>
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston#include <string.h>
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston#include <sys/types.h>
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston#include <sys/socket.h>
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston#include <netinet/in.h>
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston#include <arpa/inet.h>
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston#include <errno.h>
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston#include <unistd.h>
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston#include <netdb.h>
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston#include <fcntl.h>
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston#include "libipmi.h"
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston#include "ipmi_lan.h"
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston#include "ipmi_impl.h"
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston#define DEF_IPMI_LAN_TIMEOUT 3 /* seconds */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston#define DEF_IPMI_LAN_NUM_RETRIES 5
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston#define IPMI_LAN_CHANNEL_E 0x0e
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstontypedef struct ipmi_rs {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston uint8_t ir_data[IPMI_BUF_SIZE];
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston int ir_dlen;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_msg_hdr_t ir_ihdr;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston uint8_t ir_ccode;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston} ipmi_rs_t;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonstatic ipmi_rs_t *ipmi_lan_poll_recv(ipmi_handle_t *);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstontypedef struct ipmi_rq_entry {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_list_t ire_list;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_cmd_t ire_req;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston uint8_t ire_target_cmd;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston uint8_t ire_rq_seq;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston uint8_t *ire_msg_data;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston int ire_msg_len;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston} ipmi_rq_entry_t;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonipmi_rq_entry_t *ipmi_req_entries = NULL;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock/*
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * LAN transport-specific data
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstontypedef struct ipmi_lan {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_handle_t *il_ihp;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston char il_host[MAXHOSTNAMELEN + 1];
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston uint16_t il_port;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston char il_user[17];
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston char il_authcode[IPMI_AUTHCODE_BUF_SIZE + 1];
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston uint8_t il_challenge[16];
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston uint32_t il_session_id;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston int il_sd;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston boolean_t il_send_authcode;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston boolean_t il_session_active;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston uint8_t il_authtype;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston uint8_t il_privlvl;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston uint8_t il_num_retries;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston uint32_t il_in_seq;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston uint32_t il_timeout;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston struct sockaddr_in il_addr;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston socklen_t il_addrlen;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston} ipmi_lan_t;
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston/*
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * Calculate and returns IPMI checksum
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston *
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * Checksum algorithm is described in Section 13.8
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston *
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * d: buffer to check
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * s: position in buffer to start checksum from
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonstatic uint8_t
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonipmi_csum(uint8_t *d, int s)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston{
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston uint8_t c = 0;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston for (; s > 0; s--, d++)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston c += *d;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return (-c);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston}
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonstatic ipmi_rq_entry_t *
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonipmi_req_add_entry(ipmi_handle_t *ihp, ipmi_cmd_t *req)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston{
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_rq_entry_t *e;
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if ((e = ipmi_zalloc(ihp, sizeof (ipmi_rq_entry_t))) == NULL)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return (NULL);
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) memcpy(&e->ire_req, req, sizeof (ipmi_cmd_t));
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_list_append(&ipmi_req_entries->ire_list, e);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return (e);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston}
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston/*ARGSUSED*/
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonstatic ipmi_rq_entry_t *
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonipmi_req_lookup_entry(ipmi_handle_t *ihp, uint8_t seq, uint8_t cmd)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston{
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_rq_entry_t *e;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston for (e = ipmi_list_next(&ipmi_req_entries->ire_list); e != NULL;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston e = ipmi_list_next(e))
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (e->ire_rq_seq == seq && e->ire_req.ic_cmd == cmd)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return (e);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return (NULL);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston}
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonstatic void
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonipmi_req_remove_entry(ipmi_handle_t *ihp, uint8_t seq, uint8_t cmd)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston{
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_rq_entry_t *e;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston e = ipmi_req_lookup_entry(ihp, seq, cmd);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (e) {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_list_delete(&ipmi_req_entries->ire_list, e);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_free(ihp, e->ire_msg_data);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_free(ihp, e);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston }
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston}
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonstatic void
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonipmi_req_clear_entries(ipmi_handle_t *ihp)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston{
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_rq_entry_t *e;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
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 ipmi_free(ihp, e);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston }
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston}
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrockstatic int
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonget_random(void *buf, uint_t len)
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock{
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston int fd;
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston assert(buf != NULL && len > 0);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if ((fd = open("/dev/urandom", O_RDONLY)) < 0)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return (-1);
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (read(fd, buf, len) < 0) {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) close(fd);
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock return (-1);
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock }
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) close(fd);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return (0);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston}
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonstatic int
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonipmi_lan_send_packet(ipmi_handle_t *ihp, uint8_t *data, int dlen)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston{
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_lan_t *ilp = (ipmi_lan_t *)ihp->ih_tdata;
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return (send(ilp->il_sd, data, dlen, 0));
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston}
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonstatic ipmi_rs_t *
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonipmi_lan_recv_packet(ipmi_handle_t *ihp)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston{
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston static ipmi_rs_t rsp;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston fd_set read_set, err_set;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston struct timeval tmout;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_lan_t *ilp = (ipmi_lan_t *)ihp->ih_tdata;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston int ret;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston FD_ZERO(&read_set);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston FD_SET(ilp->il_sd, &read_set);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston FD_ZERO(&err_set);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston FD_SET(ilp->il_sd, &err_set);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston tmout.tv_sec = ilp->il_timeout;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston tmout.tv_usec = 0;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
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 !FD_ISSET(ilp->il_sd, &read_set))
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return (NULL);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /*
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 *
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 */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ret = recv(ilp->il_sd, &rsp.ir_data, IPMI_BUF_SIZE, 0);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (ret < 0) {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston FD_ZERO(&read_set);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston FD_SET(ilp->il_sd, &read_set);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston FD_ZERO(&err_set);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston FD_SET(ilp->il_sd, &err_set);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston tmout.tv_sec = ilp->il_timeout;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston tmout.tv_usec = 0;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ret = select(ilp->il_sd + 1, &read_set, NULL, &err_set, &tmout);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (ret < 0) {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (FD_ISSET(ilp->il_sd, &err_set) ||
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston !FD_ISSET(ilp->il_sd, &read_set))
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return (NULL);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ret = recv(ilp->il_sd, &rsp.ir_data, IPMI_BUF_SIZE, 0);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (ret < 0)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return (NULL);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston }
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston }
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (ret == 0)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return (NULL);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rsp.ir_data[ret] = '\0';
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rsp.ir_dlen = ret;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return (&rsp);
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock}
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston/*
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * ASF/RMCP Pong Message
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston *
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * See section 13.2.4
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonstruct rmcp_pong {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rmcp_hdr_t rp_rmcp;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston asf_hdr_t rp_asf;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston uint32_t rp_iana;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston uint32_t rp_oem;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston uint8_t rp_sup_entities;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston uint8_t rp_sup_interact;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston uint8_t rp_reserved[6];
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston};
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston/*
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * parse response RMCP "pong" packet
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston *
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 Johnston */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston/*ARGSUSED*/
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonstatic int
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonipmi_handle_pong(ipmi_handle_t *ihp, ipmi_rs_t *rsp)
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock{
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston struct rmcp_pong *pong;
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (rsp == NULL)
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock return (-1);
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /*LINTED: E_BAD_PTR_CAST_ALIGN*/
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston pong = (struct rmcp_pong *)rsp->ir_data;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return ((pong->rp_sup_entities & 0x80) ? 1 : 0);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston}
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston/*
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * Build and send RMCP presence ping message
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonstatic int
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonipmi_lan_ping(ipmi_handle_t *ihp)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston{
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rmcp_hdr_t rmcp_ping;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston asf_hdr_t asf_ping;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston uint8_t *data;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston int rv, dlen = sizeof (rmcp_ping) + sizeof (asf_ping);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) memset(&rmcp_ping, 0, sizeof (rmcp_ping));
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rmcp_ping.rh_version = RMCP_VERSION_1;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rmcp_ping.rh_msg_class = RMCP_CLASS_ASF;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rmcp_ping.rh_seq = 0xff;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) memset(&asf_ping, 0, sizeof (asf_ping));
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston asf_ping.ah_iana = htonl(ASF_RMCP_IANA);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston asf_ping.ah_msg_type = ASF_TYPE_PING;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if ((data = ipmi_zalloc(ihp, dlen)) == NULL)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return (-1);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
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
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rv = ipmi_lan_send_packet(ihp, data, dlen);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_free(ihp, data);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (rv < 0)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return (ipmi_set_error(ihp, EIPMI_LAN_PING_FAILED, NULL));
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (ipmi_lan_poll_recv(ihp) == NULL)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return (ipmi_set_error(ihp, EIPMI_LAN_PING_FAILED, NULL));
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return (0);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston}
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonstatic ipmi_rs_t *
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonipmi_lan_poll_recv(ipmi_handle_t *ihp)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston{
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rmcp_hdr_t rmcp_rsp;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_rs_t *rsp;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_rq_entry_t *entry;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston int off = 0, rv;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_lan_t *ilp = (ipmi_lan_t *)ihp->ih_tdata;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston uint8_t rsp_authtype;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rsp = ipmi_lan_recv_packet(ihp);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston while (rsp != NULL) {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /* parse response headers */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) memcpy(&rmcp_rsp, rsp->ir_data, 4);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston switch (rmcp_rsp.rh_msg_class) {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston case RMCP_CLASS_ASF:
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /* ping response packet */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rv = ipmi_handle_pong(ihp, rsp);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return ((rv <= 0) ? NULL : rsp);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston case RMCP_CLASS_IPMI:
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /* handled by rest of function */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston break;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston default:
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /* Invalid RMCP class */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rsp = ipmi_lan_recv_packet(ihp);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston continue;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston }
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston off = sizeof (rmcp_hdr_t);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rsp_authtype = rsp->ir_data[off];
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (ilp->il_send_authcode && (rsp_authtype || ilp->il_authtype))
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston off += 26;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston else
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston off += 10;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) memcpy(&rsp->ir_ihdr, (void *)(rsp->ir_data + off),
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston sizeof (rsp->ir_ihdr));
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rsp->ir_ihdr.imh_seq = rsp->ir_ihdr.imh_seq >> 2;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston off += sizeof (rsp->ir_ihdr);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rsp->ir_ccode = rsp->ir_data[off++];
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston entry = ipmi_req_lookup_entry(ihp, rsp->ir_ihdr.imh_seq,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rsp->ir_ihdr.imh_cmd);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (entry) {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_req_remove_entry(ihp, rsp->ir_ihdr.imh_seq,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rsp->ir_ihdr.imh_cmd);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston } else {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rsp = ipmi_lan_recv_packet(ihp);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston continue;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston }
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston break;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston }
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /* shift response data to start of array */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (rsp && rsp->ir_dlen > off) {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rsp->ir_dlen -= off + 1;
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_BUF_SIZE - rsp->ir_dlen);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston }
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return (rsp);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston}
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston/*
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * IPMI LAN Request Message Format
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston *
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * See section 13.8
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston *
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 Johnston */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonstatic ipmi_rq_entry_t *
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonipmi_lan_build_cmd(ipmi_handle_t *ihp, ipmi_cmd_t *req)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston{
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_lan_t *ilp = (ipmi_lan_t *)ihp->ih_tdata;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rmcp_hdr_t rmcp_hdr;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston v15_session_hdr_t session_hdr;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_msg_hdr_t msg_hdr;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston uint8_t *msg;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston int cs, tmp, off = 0, len;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_rq_entry_t *entry;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston static int curr_seq = 0;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (curr_seq >= 64)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston curr_seq = 0;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if ((entry = ipmi_req_add_entry(ihp, req)) == NULL)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return (NULL);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston len = req->ic_dlen + 29;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (ilp->il_send_authcode && ilp->il_authtype)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston len += 16;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if ((msg = ipmi_zalloc(ihp, len)) == NULL)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /* ipmi_errno set */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return (NULL);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /* RMCP header */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) memset(&rmcp_hdr, 0, sizeof (rmcp_hdr));
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rmcp_hdr.rh_version = RMCP_VERSION_1;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rmcp_hdr.rh_msg_class = RMCP_CLASS_IPMI;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rmcp_hdr.rh_seq = 0xff;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) memcpy(msg, &rmcp_hdr, sizeof (rmcp_hdr));
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston off = sizeof (rmcp_hdr);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /* IPMI session header */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) memset(&session_hdr, 0, sizeof (session_hdr));
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (! ilp->il_send_authcode)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston session_hdr.sh_authtype = 0x00;
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock else
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /* hardcode passwd authentication */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston session_hdr.sh_authtype = 0x04;
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock
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 sizeof (uint32_t));
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) memcpy(msg + off, &session_hdr, sizeof (session_hdr));
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston off += sizeof (session_hdr);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
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 off += 16;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston }
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /* message length */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston msg[off++] = req->ic_dlen + 7;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston cs = off;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /* IPMI message header */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) memset(&msg_hdr, 0, sizeof (msg_hdr));
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston msg_hdr.imh_addr1 = IPMI_BMC_SLAVE_ADDR;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston msg_hdr.imh_lun = req->ic_lun;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston msg_hdr.imh_netfn = req->ic_netfn;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston tmp = off - cs;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston msg_hdr.imh_csum = ipmi_csum(msg + cs, tmp);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston cs = off;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston msg_hdr.imh_addr2 = IPMI_BMC_SLAVE_ADDR;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston entry->ire_rq_seq = curr_seq++;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston msg_hdr.imh_seq = entry->ire_rq_seq << 2;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston msg_hdr.imh_cmd = req->ic_cmd;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) memcpy(msg + off, &msg_hdr, sizeof (msg_hdr));
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston off += sizeof (msg_hdr);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /* message data */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (req->ic_dlen != 0) {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) memcpy(msg + off, req->ic_data, req->ic_dlen);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston off += req->ic_dlen;
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock }
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /* message data checksum */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston tmp = off - cs;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston msg[off++] = ipmi_csum(msg + cs, tmp);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (ilp->il_in_seq) {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ilp->il_in_seq++;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (ilp->il_in_seq == 0)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ilp->il_in_seq++;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston }
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston entry->ire_msg_len = off;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston entry->ire_msg_data = msg;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return (entry);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston}
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonstatic int
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonipmi_lan_send(void *data, ipmi_cmd_t *cmd, ipmi_cmd_t *response,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston int *completion)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston{
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_lan_t *ilp = (ipmi_lan_t *)data;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_rq_entry_t *entry = NULL;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_rs_t *rsp = NULL;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston uint_t try = 0;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston for (;;) {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if ((entry = ipmi_lan_build_cmd(ilp->il_ihp, cmd)) == NULL)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return (-1);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (ipmi_lan_send_packet(ilp->il_ihp, entry->ire_msg_data,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston entry->ire_msg_len) < 0) {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (++try >= ilp->il_num_retries)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return (-1);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) usleep(5000);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston continue;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston }
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) usleep(100);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if ((rsp = ipmi_lan_poll_recv(ilp->il_ihp)) != NULL)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston break;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) usleep(5000);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_req_remove_entry(ilp->il_ihp, entry->ire_rq_seq,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston entry->ire_req.ic_cmd);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (++try >= ilp->il_num_retries)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return (-1);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston }
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston response->ic_netfn = rsp->ir_ihdr.imh_netfn;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston response->ic_lun = rsp->ir_ihdr.imh_lun;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston response->ic_cmd = rsp->ir_ihdr.imh_cmd;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (rsp->ir_ccode != 0) {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston *completion = rsp->ir_ccode;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston response->ic_dlen = 0;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston response->ic_data = NULL;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston } else {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston *completion = 0;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston response->ic_dlen = rsp->ir_dlen;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston response->ic_data = rsp->ir_data;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston }
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock return (0);
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock}
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston/*
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * IPMI Get Session Challenge Command
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston *
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * Copies the returned session ID and 16-byte challenge string to the supplied
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * buffers
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston *
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * See section 22.16
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston */
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrockstatic int
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonipmi_get_session_challenge_cmd(ipmi_handle_t *ihp, uint32_t *session_id,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston uint8_t *challenge)
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock{
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_cmd_t cmd, resp;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_lan_t *ilp = (ipmi_lan_t *)ihp->ih_tdata;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston char msg_data[17];
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston int ccode;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) memset(msg_data, 0, 17);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston switch (ilp->il_authtype) {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston case IPMI_SESSION_AUTHTYPE_NONE:
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston msg_data[0] = 0x00;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston break;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston case IPMI_SESSION_AUTHTYPE_MD2:
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston msg_data[0] = 0x01;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston break;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston case IPMI_SESSION_AUTHTYPE_MD5:
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston msg_data[0] = 0x02;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston break;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston case IPMI_SESSION_AUTHTYPE_PASSWORD:
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston msg_data[0] = 0x04;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston break;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston case IPMI_SESSION_AUTHTYPE_OEM:
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston msg_data[0] = 0x05;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston break;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston }
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) memcpy(msg_data + 1, ilp->il_user, 16);
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston cmd.ic_netfn = IPMI_NETFN_APP;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston cmd.ic_lun = 0;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston cmd.ic_cmd = IPMI_CMD_GET_SESSION_CHALLENGE;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston cmd.ic_data = msg_data;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston cmd.ic_dlen = 17;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (ipmi_lan_send(ilp, &cmd, &resp, &ccode) != 0 || ccode)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return (ipmi_set_error(ihp, EIPMI_LAN_CHALLENGE, NULL));
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) memcpy(session_id, resp.ic_data, 4);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) memcpy(challenge, (uint8_t *)resp.ic_data + 4, 16);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return (0);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston}
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston/*
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * IPMI Activate Session Command
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston *
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * See section 22.17
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonstatic int
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonipmi_activate_session_cmd(ipmi_handle_t *ihp)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston{
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_cmd_t cmd, resp;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_lan_t *ilp = (ipmi_lan_t *)ihp->ih_tdata;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston uint8_t msg_data[22], *resp_data;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston int ccode;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston cmd.ic_netfn = IPMI_NETFN_APP;
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock cmd.ic_lun = 0;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston cmd.ic_cmd = IPMI_CMD_ACTIVATE_SESSION;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston switch (ilp->il_authtype) {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston case IPMI_SESSION_AUTHTYPE_NONE:
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston msg_data[0] = 0x00;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston break;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston case IPMI_SESSION_AUTHTYPE_MD2:
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston msg_data[0] = 0x01;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston break;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston case IPMI_SESSION_AUTHTYPE_MD5:
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston msg_data[0] = 0x02;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston break;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston case IPMI_SESSION_AUTHTYPE_PASSWORD:
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston msg_data[0] = 0x04;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston break;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston case IPMI_SESSION_AUTHTYPE_OEM:
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston msg_data[0] = 0x05;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston break;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston }
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston msg_data[1] = ilp->il_privlvl;
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) memcpy(msg_data + 2, ilp->il_challenge, 16);
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /* setup initial outbound sequence number */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) get_random(msg_data + 18, 4);
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston cmd.ic_data = msg_data;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston cmd.ic_dlen = 22;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ilp->il_send_authcode = B_TRUE;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (ipmi_lan_send(ilp, &cmd, &resp, &ccode) != 0 || ccode) {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ilp->il_send_authcode = B_FALSE;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return (ipmi_set_error(ihp, EIPMI_LAN_SESSION, NULL));
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock }
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston resp_data = (uint8_t *)resp.ic_data;
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 resp_data[6] << 8 | resp_data[5];
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (ilp->il_in_seq == 0)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ++ilp->il_in_seq;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock return (0);
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock}
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston/*
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * See section 22.18
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston *
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * returns privilege level or -1 on error
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonstatic int
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonipmi_set_session_privlvl_cmd(ipmi_handle_t *ihp, uint8_t privlvl)
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock{
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_cmd_t cmd, resp;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston int ret = 0, ccode;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (privlvl > IPMI_SESSION_PRIV_OEM)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return (ipmi_set_error(ihp, EIPMI_BADPARAM, NULL));
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston cmd.ic_netfn = IPMI_NETFN_APP;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston cmd.ic_lun = 0;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston cmd.ic_cmd = IPMI_CMD_SET_SESSION_PRIVLVL;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston cmd.ic_data = &privlvl;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston cmd.ic_dlen = 1;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
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
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return (ret);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston}
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston/*
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * See section 22.19
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonstatic int
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonipmi_close_session_cmd(ipmi_handle_t *ihp)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston{
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_lan_t *ilp = (ipmi_lan_t *)ihp->ih_tdata;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_cmd_t cmd, resp;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston uint8_t msg_data[4];
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston int ret = 0, ccode;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (! ilp->il_session_active)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return (-1);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) memcpy(&msg_data, &ilp->il_session_id, 4);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston cmd.ic_netfn = IPMI_NETFN_APP;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston cmd.ic_lun = 0;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston cmd.ic_cmd = IPMI_CMD_CLOSE_SESSION;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston cmd.ic_data = msg_data;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston cmd.ic_dlen = 4;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (ipmi_lan_send(ilp, &cmd, &resp, &ccode) != 0)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ret = -1;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return (ret);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston}
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston/*
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * IPMI LAN Session Activation
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston *
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * See section 13.14
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston *
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 Johnston */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonstatic int
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonipmi_lan_activate_session(ipmi_handle_t *ihp)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston{
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_lan_t *ilp = (ipmi_lan_t *)ihp->ih_tdata;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_channel_auth_caps_t *ac;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (ipmi_lan_ping(ihp) != 0)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return (-1);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if ((ac = ipmi_get_channel_auth_caps(ihp, IPMI_LAN_CHANNEL_E,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ilp->il_privlvl)) == NULL)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return (-1);
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock /*
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.
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (!(ac->cap_authtype & IPMI_SESSION_AUTHTYPE_PASSWORD)) {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston free(ac);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return (ipmi_set_error(ihp, EIPMI_LAN_PASSWD_NOTSUP, NULL));
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston }
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston free(ac);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (ipmi_get_session_challenge_cmd(ihp, &ilp->il_session_id,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ilp->il_challenge) != 0)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return (-1);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (ipmi_activate_session_cmd(ihp) != 0)
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock return (-1);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ilp->il_session_active = B_TRUE;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (ipmi_set_session_privlvl_cmd(ihp, ilp->il_privlvl) != 0)
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock return (-1);
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return (0);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston}
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonstatic void
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonipmi_lan_close(void *data)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston{
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_lan_t *ilp = (ipmi_lan_t *)data;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (ilp->il_session_active)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) ipmi_close_session_cmd(ilp->il_ihp);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (ilp->il_sd >= 0)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) close(ilp->il_sd);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_req_clear_entries(ilp->il_ihp);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_free(ilp->il_ihp, ipmi_req_entries);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_free(ilp->il_ihp, ilp);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston}
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonstatic void *
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonipmi_lan_open(ipmi_handle_t *ihp, nvlist_t *params)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston{
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston int rc;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston struct hostent *host;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_lan_t *ilp;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston char *hostname, *user, *authcode;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if ((ilp = ipmi_zalloc(ihp, sizeof (ipmi_lan_t))) == NULL) {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /* ipmi errno set */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return (NULL);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston }
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ilp->il_ihp = ihp;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ihp->ih_tdata = ilp;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock /*
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 *
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * If any of these were not specified then we abort
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock */
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 ipmi_free(ihp, ilp);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) ipmi_set_error(ihp, EIPMI_BADPARAM, NULL);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return (NULL);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston }
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) strncpy(ilp->il_host, hostname, MAXHOSTNAMELEN);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) strncpy(ilp->il_user, user, 16);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) strncpy(ilp->il_authcode, authcode, 16);
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /*
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 */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (nvlist_lookup_uint16(params, IPMI_LAN_PORT, &ilp->il_port))
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ilp->il_port = RMCP_UDP_PORT;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (nvlist_lookup_uint8(params, IPMI_LAN_PRIVLVL, &ilp->il_privlvl))
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ilp->il_privlvl = IPMI_SESSION_PRIV_ADMIN;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (nvlist_lookup_uint32(params, IPMI_LAN_TIMEOUT, &ilp->il_timeout))
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ilp->il_timeout = DEF_IPMI_LAN_TIMEOUT;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (nvlist_lookup_uint8(params, IPMI_LAN_NUM_RETRIES,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston &ilp->il_num_retries))
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ilp->il_num_retries = DEF_IPMI_LAN_NUM_RETRIES;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ilp->il_authtype = IPMI_SESSION_AUTHTYPE_PASSWORD;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /*
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * Open up and connect a UDP socket between us and the service
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * processor
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ilp->il_addr.sin_family = AF_INET;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ilp->il_addr.sin_port = htons(ilp->il_port);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rc = inet_pton(AF_INET, (const char *)ilp->il_host,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston &ilp->il_addr.sin_addr);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (rc <= 0) {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if ((host = gethostbyname((const char *)ilp->il_host))
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston == NULL) {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_free(ihp, ilp);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) ipmi_set_error(ihp, EIPMI_LAN_OPEN_FAILED, NULL);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return (NULL);
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock }
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ilp->il_addr.sin_family = host->h_addrtype;
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) memcpy(&ilp->il_addr.sin_addr, host->h_addr,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston host->h_length);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston }
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if ((ilp->il_sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_free(ihp, ilp);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) ipmi_set_error(ihp, EIPMI_LAN_OPEN_FAILED, NULL);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return (NULL);
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock }
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (connect(ilp->il_sd, (struct sockaddr *)&ilp->il_addr,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston sizeof (struct sockaddr_in)) < 0) {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_lan_close(ilp);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) ipmi_set_error(ihp, EIPMI_LAN_OPEN_FAILED, NULL);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return (NULL);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston }
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if ((ipmi_req_entries = ipmi_zalloc(ihp, sizeof (ipmi_rq_entry_t)))
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston == NULL)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return (NULL);
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock /*
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * Finally we start up the IPMI LAN session
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if ((rc = ipmi_lan_activate_session(ihp)) < 0) {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_lan_close(ilp);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return (NULL);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston }
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return (ilp);
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock}
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonipmi_transport_t ipmi_transport_lan = {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_lan_open,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_lan_close,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ipmi_lan_send
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston};