4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
31 #include <sys/types.h>
32 #include <sys/socket.h>
33 #include <netinet/in.h>
34 #include <arpa/inet.h>
42 #include "ipmi_impl.h"
44 #define DEF_IPMI_LAN_TIMEOUT 3 /* seconds */
45 #define DEF_IPMI_LAN_NUM_RETRIES 5
46 #define IPMI_LAN_CHANNEL_E 0x0e
48 typedef struct ipmi_rs
{
49 uint8_t ir_data
[IPMI_BUF_SIZE
];
51 ipmi_msg_hdr_t ir_ihdr
;
55 static ipmi_rs_t
*ipmi_lan_poll_recv(ipmi_handle_t
*);
57 typedef struct ipmi_rq_entry
{
60 uint8_t ire_target_cmd
;
62 uint8_t *ire_msg_data
;
66 ipmi_rq_entry_t
*ipmi_req_entries
= NULL
;
69 * LAN transport-specific data
71 typedef struct ipmi_lan
{
72 ipmi_handle_t
*il_ihp
;
73 char il_host
[MAXHOSTNAMELEN
+ 1];
76 char il_authcode
[IPMI_AUTHCODE_BUF_SIZE
+ 1];
77 uint8_t il_challenge
[16];
78 uint32_t il_session_id
;
80 boolean_t il_send_authcode
;
81 boolean_t il_session_active
;
84 uint8_t il_num_retries
;
87 struct sockaddr_in il_addr
;
92 * Calculate and returns IPMI checksum
94 * Checksum algorithm is described in Section 13.8
97 * s: position in buffer to start checksum from
100 ipmi_csum(uint8_t *d
, int s
)
103 for (; s
> 0; s
--, d
++)
108 static ipmi_rq_entry_t
*
109 ipmi_req_add_entry(ipmi_handle_t
*ihp
, ipmi_cmd_t
*req
)
113 if ((e
= ipmi_zalloc(ihp
, sizeof (ipmi_rq_entry_t
))) == NULL
)
116 (void) memcpy(&e
->ire_req
, req
, sizeof (ipmi_cmd_t
));
117 ipmi_list_append(&ipmi_req_entries
->ire_list
, e
);
123 static ipmi_rq_entry_t
*
124 ipmi_req_lookup_entry(ipmi_handle_t
*ihp
, uint8_t seq
, uint8_t cmd
)
128 for (e
= ipmi_list_next(&ipmi_req_entries
->ire_list
); e
!= NULL
;
129 e
= ipmi_list_next(e
))
130 if (e
->ire_rq_seq
== seq
&& e
->ire_req
.ic_cmd
== cmd
)
137 ipmi_req_remove_entry(ipmi_handle_t
*ihp
, uint8_t seq
, uint8_t cmd
)
141 e
= ipmi_req_lookup_entry(ihp
, seq
, cmd
);
144 ipmi_list_delete(&ipmi_req_entries
->ire_list
, e
);
145 ipmi_free(ihp
, e
->ire_msg_data
);
151 ipmi_req_clear_entries(ipmi_handle_t
*ihp
)
155 while ((e
= ipmi_list_next(&ipmi_req_entries
->ire_list
)) != NULL
) {
156 ipmi_list_delete(&ipmi_req_entries
->ire_list
, e
);
162 get_random(void *buf
, uint_t len
)
166 assert(buf
!= NULL
&& len
> 0);
167 if ((fd
= open("/dev/urandom", O_RDONLY
)) < 0)
170 if (read(fd
, buf
, len
) < 0) {
179 ipmi_lan_send_packet(ipmi_handle_t
*ihp
, uint8_t *data
, int dlen
)
181 ipmi_lan_t
*ilp
= (ipmi_lan_t
*)ihp
->ih_tdata
;
183 return (send(ilp
->il_sd
, data
, dlen
, 0));
187 ipmi_lan_recv_packet(ipmi_handle_t
*ihp
)
189 static ipmi_rs_t rsp
;
190 fd_set read_set
, err_set
;
191 struct timeval tmout
;
192 ipmi_lan_t
*ilp
= (ipmi_lan_t
*)ihp
->ih_tdata
;
196 FD_SET(ilp
->il_sd
, &read_set
);
199 FD_SET(ilp
->il_sd
, &err_set
);
201 tmout
.tv_sec
= ilp
->il_timeout
;
204 ret
= select(ilp
->il_sd
+ 1, &read_set
, NULL
, &err_set
, &tmout
);
205 if (ret
< 0 || FD_ISSET(ilp
->il_sd
, &err_set
) ||
206 !FD_ISSET(ilp
->il_sd
, &read_set
))
210 * The first read may return ECONNREFUSED because the rmcp ping
211 * packet--sent to UDP port 623--will be processed by both the
214 * The problem with this is that the ECONNREFUSED takes
215 * priority over any other received datagram; that means that
216 * the Connection Refused shows up _before_ the response packet,
217 * regardless of the order they were sent out. (unless the
218 * response is read before the connection refused is returned)
220 ret
= recv(ilp
->il_sd
, &rsp
.ir_data
, IPMI_BUF_SIZE
, 0);
224 FD_SET(ilp
->il_sd
, &read_set
);
227 FD_SET(ilp
->il_sd
, &err_set
);
229 tmout
.tv_sec
= ilp
->il_timeout
;
232 ret
= select(ilp
->il_sd
+ 1, &read_set
, NULL
, &err_set
, &tmout
);
234 if (FD_ISSET(ilp
->il_sd
, &err_set
) ||
235 !FD_ISSET(ilp
->il_sd
, &read_set
))
238 ret
= recv(ilp
->il_sd
, &rsp
.ir_data
, IPMI_BUF_SIZE
, 0);
247 rsp
.ir_data
[ret
] = '\0';
255 * ASF/RMCP Pong Message
264 uint8_t rp_sup_entities
;
265 uint8_t rp_sup_interact
;
266 uint8_t rp_reserved
[6];
270 * parse response RMCP "pong" packet
272 * return -1 if ping response not received
273 * returns 0 if IPMI is NOT supported
274 * returns 1 if IPMI is supported
278 ipmi_handle_pong(ipmi_handle_t
*ihp
, ipmi_rs_t
*rsp
)
280 struct rmcp_pong
*pong
;
285 /*LINTED: E_BAD_PTR_CAST_ALIGN*/
286 pong
= (struct rmcp_pong
*)rsp
->ir_data
;
288 return ((pong
->rp_sup_entities
& 0x80) ? 1 : 0);
292 * Build and send RMCP presence ping message
295 ipmi_lan_ping(ipmi_handle_t
*ihp
)
297 rmcp_hdr_t rmcp_ping
;
300 int rv
, dlen
= sizeof (rmcp_ping
) + sizeof (asf_ping
);
302 (void) memset(&rmcp_ping
, 0, sizeof (rmcp_ping
));
303 rmcp_ping
.rh_version
= RMCP_VERSION_1
;
304 rmcp_ping
.rh_msg_class
= RMCP_CLASS_ASF
;
305 rmcp_ping
.rh_seq
= 0xff;
307 (void) memset(&asf_ping
, 0, sizeof (asf_ping
));
308 asf_ping
.ah_iana
= htonl(ASF_RMCP_IANA
);
309 asf_ping
.ah_msg_type
= ASF_TYPE_PING
;
311 if ((data
= ipmi_zalloc(ihp
, dlen
)) == NULL
)
314 (void) memcpy(data
, &rmcp_ping
, sizeof (rmcp_ping
));
315 (void) memcpy(data
+ sizeof (rmcp_ping
), &asf_ping
, sizeof (asf_ping
));
317 rv
= ipmi_lan_send_packet(ihp
, data
, dlen
);
319 ipmi_free(ihp
, data
);
322 return (ipmi_set_error(ihp
, EIPMI_LAN_PING_FAILED
, NULL
));
324 if (ipmi_lan_poll_recv(ihp
) == NULL
)
325 return (ipmi_set_error(ihp
, EIPMI_LAN_PING_FAILED
, NULL
));
331 ipmi_lan_poll_recv(ipmi_handle_t
*ihp
)
335 ipmi_rq_entry_t
*entry
;
337 ipmi_lan_t
*ilp
= (ipmi_lan_t
*)ihp
->ih_tdata
;
338 uint8_t rsp_authtype
;
340 rsp
= ipmi_lan_recv_packet(ihp
);
342 while (rsp
!= NULL
) {
344 /* parse response headers */
345 (void) memcpy(&rmcp_rsp
, rsp
->ir_data
, 4);
347 switch (rmcp_rsp
.rh_msg_class
) {
349 /* ping response packet */
350 rv
= ipmi_handle_pong(ihp
, rsp
);
351 return ((rv
<= 0) ? NULL
: rsp
);
352 case RMCP_CLASS_IPMI
:
353 /* handled by rest of function */
356 /* Invalid RMCP class */
357 rsp
= ipmi_lan_recv_packet(ihp
);
361 off
= sizeof (rmcp_hdr_t
);
362 rsp_authtype
= rsp
->ir_data
[off
];
363 if (ilp
->il_send_authcode
&& (rsp_authtype
|| ilp
->il_authtype
))
368 (void) memcpy(&rsp
->ir_ihdr
, (void *)(rsp
->ir_data
+ off
),
369 sizeof (rsp
->ir_ihdr
));
370 rsp
->ir_ihdr
.imh_seq
= rsp
->ir_ihdr
.imh_seq
>> 2;
371 off
+= sizeof (rsp
->ir_ihdr
);
372 rsp
->ir_ccode
= rsp
->ir_data
[off
++];
374 entry
= ipmi_req_lookup_entry(ihp
, rsp
->ir_ihdr
.imh_seq
,
375 rsp
->ir_ihdr
.imh_cmd
);
377 ipmi_req_remove_entry(ihp
, rsp
->ir_ihdr
.imh_seq
,
378 rsp
->ir_ihdr
.imh_cmd
);
380 rsp
= ipmi_lan_recv_packet(ihp
);
386 /* shift response data to start of array */
387 if (rsp
&& rsp
->ir_dlen
> off
) {
388 rsp
->ir_dlen
-= off
+ 1;
389 (void) memmove(rsp
->ir_data
, rsp
->ir_data
+ off
, rsp
->ir_dlen
);
390 (void) memset(rsp
->ir_data
+ rsp
->ir_dlen
, 0,
391 IPMI_BUF_SIZE
- rsp
->ir_dlen
);
397 * IPMI LAN Request Message Format
401 * +---------------------+
402 * | rmcp_hdr_t | 4 bytes
403 * +---------------------+
404 * | v15_session_hdr_t | 9 bytes
405 * +---------------------+
406 * | [authcode] | 16 bytes (if AUTHTYPE != none)
407 * +---------------------+
408 * | msg length | 1 byte
409 * +---------------------+
410 * | ipmi_msg_hdr_t | 6 bytes
411 * +---------------------+
412 * | [msg data] | variable
413 * +---------------------+
414 * | msg data checksum | 1 byte
415 * +---------------------+
417 static ipmi_rq_entry_t
*
418 ipmi_lan_build_cmd(ipmi_handle_t
*ihp
, ipmi_cmd_t
*req
)
420 ipmi_lan_t
*ilp
= (ipmi_lan_t
*)ihp
->ih_tdata
;
422 v15_session_hdr_t session_hdr
;
423 ipmi_msg_hdr_t msg_hdr
;
425 int cs
, tmp
, off
= 0, len
;
426 ipmi_rq_entry_t
*entry
;
427 static int curr_seq
= 0;
432 if ((entry
= ipmi_req_add_entry(ihp
, req
)) == NULL
)
435 len
= req
->ic_dlen
+ 29;
436 if (ilp
->il_send_authcode
&& ilp
->il_authtype
)
439 if ((msg
= ipmi_zalloc(ihp
, len
)) == NULL
)
444 (void) memset(&rmcp_hdr
, 0, sizeof (rmcp_hdr
));
445 rmcp_hdr
.rh_version
= RMCP_VERSION_1
;
446 rmcp_hdr
.rh_msg_class
= RMCP_CLASS_IPMI
;
447 rmcp_hdr
.rh_seq
= 0xff;
448 (void) memcpy(msg
, &rmcp_hdr
, sizeof (rmcp_hdr
));
449 off
= sizeof (rmcp_hdr
);
451 /* IPMI session header */
452 (void) memset(&session_hdr
, 0, sizeof (session_hdr
));
453 if (! ilp
->il_send_authcode
)
454 session_hdr
.sh_authtype
= 0x00;
456 /* hardcode passwd authentication */
457 session_hdr
.sh_authtype
= 0x04;
459 (void) memcpy(&session_hdr
.sh_seq
, &ilp
->il_in_seq
, sizeof (uint32_t));
460 (void) memcpy(&session_hdr
.sh_id
, &ilp
->il_session_id
,
463 (void) memcpy(msg
+ off
, &session_hdr
, sizeof (session_hdr
));
464 off
+= sizeof (session_hdr
);
466 /* IPMI session authcode */
467 if (ilp
->il_send_authcode
&& ilp
->il_authtype
) {
468 (void) memcpy(msg
+ off
, ilp
->il_authcode
, 16);
473 msg
[off
++] = req
->ic_dlen
+ 7;
476 /* IPMI message header */
477 (void) memset(&msg_hdr
, 0, sizeof (msg_hdr
));
478 msg_hdr
.imh_addr1
= IPMI_BMC_SLAVE_ADDR
;
479 msg_hdr
.imh_lun
= req
->ic_lun
;
480 msg_hdr
.imh_netfn
= req
->ic_netfn
;
482 msg_hdr
.imh_csum
= ipmi_csum(msg
+ cs
, tmp
);
484 msg_hdr
.imh_addr2
= IPMI_BMC_SLAVE_ADDR
;
485 entry
->ire_rq_seq
= curr_seq
++;
486 msg_hdr
.imh_seq
= entry
->ire_rq_seq
<< 2;
487 msg_hdr
.imh_cmd
= req
->ic_cmd
;
488 (void) memcpy(msg
+ off
, &msg_hdr
, sizeof (msg_hdr
));
489 off
+= sizeof (msg_hdr
);
492 if (req
->ic_dlen
!= 0) {
493 (void) memcpy(msg
+ off
, req
->ic_data
, req
->ic_dlen
);
497 /* message data checksum */
499 msg
[off
++] = ipmi_csum(msg
+ cs
, tmp
);
501 if (ilp
->il_in_seq
) {
503 if (ilp
->il_in_seq
== 0)
507 entry
->ire_msg_len
= off
;
508 entry
->ire_msg_data
= msg
;
514 ipmi_lan_send(void *data
, ipmi_cmd_t
*cmd
, ipmi_cmd_t
*response
,
517 ipmi_lan_t
*ilp
= (ipmi_lan_t
*)data
;
518 ipmi_rq_entry_t
*entry
= NULL
;
519 ipmi_rs_t
*rsp
= NULL
;
523 if ((entry
= ipmi_lan_build_cmd(ilp
->il_ihp
, cmd
)) == NULL
)
526 if (ipmi_lan_send_packet(ilp
->il_ihp
, entry
->ire_msg_data
,
527 entry
->ire_msg_len
) < 0) {
528 if (++try >= ilp
->il_num_retries
)
536 if ((rsp
= ipmi_lan_poll_recv(ilp
->il_ihp
)) != NULL
)
540 ipmi_req_remove_entry(ilp
->il_ihp
, entry
->ire_rq_seq
,
541 entry
->ire_req
.ic_cmd
);
543 if (++try >= ilp
->il_num_retries
)
546 response
->ic_netfn
= rsp
->ir_ihdr
.imh_netfn
;
547 response
->ic_lun
= rsp
->ir_ihdr
.imh_lun
;
548 response
->ic_cmd
= rsp
->ir_ihdr
.imh_cmd
;
549 if (rsp
->ir_ccode
!= 0) {
550 *completion
= rsp
->ir_ccode
;
551 response
->ic_dlen
= 0;
552 response
->ic_data
= NULL
;
555 response
->ic_dlen
= rsp
->ir_dlen
;
556 response
->ic_data
= rsp
->ir_data
;
562 * IPMI Get Session Challenge Command
564 * Copies the returned session ID and 16-byte challenge string to the supplied
570 ipmi_get_session_challenge_cmd(ipmi_handle_t
*ihp
, uint32_t *session_id
,
573 ipmi_cmd_t cmd
, resp
;
574 ipmi_lan_t
*ilp
= (ipmi_lan_t
*)ihp
->ih_tdata
;
578 (void) memset(msg_data
, 0, 17);
580 switch (ilp
->il_authtype
) {
581 case IPMI_SESSION_AUTHTYPE_NONE
:
584 case IPMI_SESSION_AUTHTYPE_MD2
:
587 case IPMI_SESSION_AUTHTYPE_MD5
:
590 case IPMI_SESSION_AUTHTYPE_PASSWORD
:
593 case IPMI_SESSION_AUTHTYPE_OEM
:
597 (void) memcpy(msg_data
+ 1, ilp
->il_user
, 16);
599 cmd
.ic_netfn
= IPMI_NETFN_APP
;
601 cmd
.ic_cmd
= IPMI_CMD_GET_SESSION_CHALLENGE
;
602 cmd
.ic_data
= msg_data
;
605 if (ipmi_lan_send(ilp
, &cmd
, &resp
, &ccode
) != 0 || ccode
)
606 return (ipmi_set_error(ihp
, EIPMI_LAN_CHALLENGE
, NULL
));
608 (void) memcpy(session_id
, resp
.ic_data
, 4);
609 (void) memcpy(challenge
, (uint8_t *)resp
.ic_data
+ 4, 16);
615 * IPMI Activate Session Command
620 ipmi_activate_session_cmd(ipmi_handle_t
*ihp
)
622 ipmi_cmd_t cmd
, resp
;
623 ipmi_lan_t
*ilp
= (ipmi_lan_t
*)ihp
->ih_tdata
;
624 uint8_t msg_data
[22], *resp_data
;
627 cmd
.ic_netfn
= IPMI_NETFN_APP
;
629 cmd
.ic_cmd
= IPMI_CMD_ACTIVATE_SESSION
;
631 switch (ilp
->il_authtype
) {
632 case IPMI_SESSION_AUTHTYPE_NONE
:
635 case IPMI_SESSION_AUTHTYPE_MD2
:
638 case IPMI_SESSION_AUTHTYPE_MD5
:
641 case IPMI_SESSION_AUTHTYPE_PASSWORD
:
644 case IPMI_SESSION_AUTHTYPE_OEM
:
648 msg_data
[1] = ilp
->il_privlvl
;
650 (void) memcpy(msg_data
+ 2, ilp
->il_challenge
, 16);
652 /* setup initial outbound sequence number */
653 (void) get_random(msg_data
+ 18, 4);
655 cmd
.ic_data
= msg_data
;
658 ilp
->il_send_authcode
= B_TRUE
;
660 if (ipmi_lan_send(ilp
, &cmd
, &resp
, &ccode
) != 0 || ccode
) {
661 ilp
->il_send_authcode
= B_FALSE
;
662 return (ipmi_set_error(ihp
, EIPMI_LAN_SESSION
, NULL
));
665 resp_data
= (uint8_t *)resp
.ic_data
;
666 (void) memcpy(&ilp
->il_session_id
, resp_data
+ 1, 4);
667 ilp
->il_in_seq
= resp_data
[8] << 24 | resp_data
[7] << 16 |
668 resp_data
[6] << 8 | resp_data
[5];
669 if (ilp
->il_in_seq
== 0)
679 * returns privilege level or -1 on error
682 ipmi_set_session_privlvl_cmd(ipmi_handle_t
*ihp
, uint8_t privlvl
)
684 ipmi_cmd_t cmd
, resp
;
687 if (privlvl
> IPMI_SESSION_PRIV_OEM
)
688 return (ipmi_set_error(ihp
, EIPMI_BADPARAM
, NULL
));
690 cmd
.ic_netfn
= IPMI_NETFN_APP
;
692 cmd
.ic_cmd
= IPMI_CMD_SET_SESSION_PRIVLVL
;
693 cmd
.ic_data
= &privlvl
;
696 if (ipmi_lan_send(ihp
->ih_tdata
, &cmd
, &resp
, &ccode
) != 0)
697 ret
= ipmi_set_error(ihp
, EIPMI_LAN_SETPRIV
, NULL
);
706 ipmi_close_session_cmd(ipmi_handle_t
*ihp
)
708 ipmi_lan_t
*ilp
= (ipmi_lan_t
*)ihp
->ih_tdata
;
709 ipmi_cmd_t cmd
, resp
;
713 if (! ilp
->il_session_active
)
716 (void) memcpy(&msg_data
, &ilp
->il_session_id
, 4);
718 cmd
.ic_netfn
= IPMI_NETFN_APP
;
720 cmd
.ic_cmd
= IPMI_CMD_CLOSE_SESSION
;
721 cmd
.ic_data
= msg_data
;
724 if (ipmi_lan_send(ilp
, &cmd
, &resp
, &ccode
) != 0)
731 * IPMI LAN Session Activation
735 * 1. send "RMCP Presence Ping" message, response message will
736 * indicate whether the platform supports IPMI
737 * 2. send "Get Channel Authentication Capabilities" command
738 * with AUTHTYPE = none, response packet will contain information
739 * about supported challenge/response authentication types
740 * 3. send "Get Session Challenge" command with AUTHTYPE = none
741 * and indicate the authentication type in the message, response
742 * packet will contain challenge string and temporary session ID.
743 * 4. send "Activate Session" command, authenticated with AUTHTYPE
744 * sent in previous message. Also sends the initial value for
745 * the outbound sequence number for BMC.
746 * 5. BMC returns response confirming session activation and
747 * session ID for this session and initial inbound sequence.
750 ipmi_lan_activate_session(ipmi_handle_t
*ihp
)
752 ipmi_lan_t
*ilp
= (ipmi_lan_t
*)ihp
->ih_tdata
;
753 ipmi_channel_auth_caps_t
*ac
;
755 if (ipmi_lan_ping(ihp
) != 0)
758 if ((ac
= ipmi_get_channel_auth_caps(ihp
, IPMI_LAN_CHANNEL_E
,
759 ilp
->il_privlvl
)) == NULL
)
763 * For the sake of simplicity, we're just supporting basic password
764 * authentication. If this authentication type is not supported then
767 if (!(ac
->cap_authtype
& IPMI_SESSION_AUTHTYPE_PASSWORD
)) {
769 return (ipmi_set_error(ihp
, EIPMI_LAN_PASSWD_NOTSUP
, NULL
));
773 if (ipmi_get_session_challenge_cmd(ihp
, &ilp
->il_session_id
,
774 ilp
->il_challenge
) != 0)
777 if (ipmi_activate_session_cmd(ihp
) != 0)
780 ilp
->il_session_active
= B_TRUE
;
782 if (ipmi_set_session_privlvl_cmd(ihp
, ilp
->il_privlvl
) != 0)
789 ipmi_lan_close(void *data
)
791 ipmi_lan_t
*ilp
= (ipmi_lan_t
*)data
;
793 if (ilp
->il_session_active
)
794 (void) ipmi_close_session_cmd(ilp
->il_ihp
);
797 (void) close(ilp
->il_sd
);
799 ipmi_req_clear_entries(ilp
->il_ihp
);
800 ipmi_free(ilp
->il_ihp
, ipmi_req_entries
);
801 ipmi_free(ilp
->il_ihp
, ilp
);
805 ipmi_lan_open(ipmi_handle_t
*ihp
, nvlist_t
*params
)
808 struct hostent
*host
;
810 char *hostname
, *user
, *authcode
;
812 if ((ilp
= ipmi_zalloc(ihp
, sizeof (ipmi_lan_t
))) == NULL
) {
820 * Parse the parameters passed in the params nvlist. The following
821 * parameters are required
822 * IPMI_LAN_HOST, IPMI_LAN_USER and IPMI_LAN_PASSWD
824 * If any of these were not specified then we abort
826 if (nvlist_lookup_string(params
, IPMI_LAN_HOST
, &hostname
) ||
827 nvlist_lookup_string(params
, IPMI_LAN_USER
, &user
) ||
828 nvlist_lookup_string(params
, IPMI_LAN_PASSWD
, &authcode
)) {
830 (void) ipmi_set_error(ihp
, EIPMI_BADPARAM
, NULL
);
833 (void) strncpy(ilp
->il_host
, hostname
, MAXHOSTNAMELEN
);
834 (void) strncpy(ilp
->il_user
, user
, 16);
835 (void) strncpy(ilp
->il_authcode
, authcode
, 16);
838 * IPMI_LAN_PORT is an optional parameter and defaults to port 623
839 * IPMI_LAN_PRIVLVL is also optional and defaults to admin
840 * IPMI_LAN_TIMEOUT is optional and will default to 3 seconds
841 * IPMI_LAN_NUM_RETIES is optional and will default to 5
843 if (nvlist_lookup_uint16(params
, IPMI_LAN_PORT
, &ilp
->il_port
))
844 ilp
->il_port
= RMCP_UDP_PORT
;
846 if (nvlist_lookup_uint8(params
, IPMI_LAN_PRIVLVL
, &ilp
->il_privlvl
))
847 ilp
->il_privlvl
= IPMI_SESSION_PRIV_ADMIN
;
849 if (nvlist_lookup_uint32(params
, IPMI_LAN_TIMEOUT
, &ilp
->il_timeout
))
850 ilp
->il_timeout
= DEF_IPMI_LAN_TIMEOUT
;
852 if (nvlist_lookup_uint8(params
, IPMI_LAN_NUM_RETRIES
,
853 &ilp
->il_num_retries
))
854 ilp
->il_num_retries
= DEF_IPMI_LAN_NUM_RETRIES
;
856 ilp
->il_authtype
= IPMI_SESSION_AUTHTYPE_PASSWORD
;
859 * Open up and connect a UDP socket between us and the service
862 ilp
->il_addr
.sin_family
= AF_INET
;
863 ilp
->il_addr
.sin_port
= htons(ilp
->il_port
);
865 rc
= inet_pton(AF_INET
, (const char *)ilp
->il_host
,
866 &ilp
->il_addr
.sin_addr
);
868 if ((host
= gethostbyname((const char *)ilp
->il_host
))
871 (void) ipmi_set_error(ihp
, EIPMI_LAN_OPEN_FAILED
, NULL
);
874 ilp
->il_addr
.sin_family
= host
->h_addrtype
;
875 (void) memcpy(&ilp
->il_addr
.sin_addr
, host
->h_addr
,
879 if ((ilp
->il_sd
= socket(AF_INET
, SOCK_DGRAM
, IPPROTO_UDP
)) < 0) {
881 (void) ipmi_set_error(ihp
, EIPMI_LAN_OPEN_FAILED
, NULL
);
884 if (connect(ilp
->il_sd
, (struct sockaddr
*)&ilp
->il_addr
,
885 sizeof (struct sockaddr_in
)) < 0) {
887 (void) ipmi_set_error(ihp
, EIPMI_LAN_OPEN_FAILED
, NULL
);
891 if ((ipmi_req_entries
= ipmi_zalloc(ihp
, sizeof (ipmi_rq_entry_t
)))
896 * Finally we start up the IPMI LAN session
898 if ((rc
= ipmi_lan_activate_session(ihp
)) < 0) {
906 ipmi_transport_t ipmi_transport_lan
= {