mirror of
https://github.com/ipmitool/ipmitool.git
synced 2025-05-10 18:47:22 +00:00
changes to handle session structure inside of intf structure
This commit is contained in:
parent
9ba83a2c5d
commit
c96ef9d425
@ -52,20 +52,23 @@
|
|||||||
#include <ipmitool/helper.h>
|
#include <ipmitool/helper.h>
|
||||||
#include <ipmitool/bswap.h>
|
#include <ipmitool/bswap.h>
|
||||||
#include <ipmitool/ipmi.h>
|
#include <ipmitool/ipmi.h>
|
||||||
|
#include <ipmitool/ipmi_intf.h>
|
||||||
#if HAVE_CONFIG_H
|
#if HAVE_CONFIG_H
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#include "lan.h"
|
#include "lan.h"
|
||||||
#include "md5.h"
|
#include "md5.h"
|
||||||
#include "rmcp.h"
|
#include "rmcp.h"
|
||||||
#include "asf.h"
|
#include "asf.h"
|
||||||
|
|
||||||
|
extern const struct valstr ipmi_privlvl_vals[];
|
||||||
|
extern const struct valstr ipmi_authtype_vals[];
|
||||||
|
|
||||||
struct ipmi_rq_entry * ipmi_req_entries;
|
struct ipmi_rq_entry * ipmi_req_entries;
|
||||||
static struct ipmi_rq_entry * ipmi_req_entries_tail;
|
static struct ipmi_rq_entry * ipmi_req_entries_tail;
|
||||||
|
|
||||||
int verbose;
|
extern int verbose;
|
||||||
|
|
||||||
const struct valstr ipmi_authtype_session_vals[] = {
|
const struct valstr ipmi_authtype_session_vals[] = {
|
||||||
{ IPMI_SESSION_AUTHTYPE_NONE, "NONE" },
|
{ IPMI_SESSION_AUTHTYPE_NONE, "NONE" },
|
||||||
@ -77,9 +80,7 @@ const struct valstr ipmi_authtype_session_vals[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static int recv_timeout = IPMI_LAN_TIMEOUT;
|
static int recv_timeout = IPMI_LAN_TIMEOUT;
|
||||||
static int curr_seq;
|
|
||||||
static sigjmp_buf jmpbuf;
|
static sigjmp_buf jmpbuf;
|
||||||
struct ipmi_session lan_session;
|
|
||||||
|
|
||||||
static int ipmi_lan_send_packet(struct ipmi_intf * intf, unsigned char * data, int data_len);
|
static int ipmi_lan_send_packet(struct ipmi_intf * intf, unsigned char * data, int data_len);
|
||||||
static struct ipmi_rs * ipmi_lan_recv_packet(struct ipmi_intf * intf);
|
static struct ipmi_rs * ipmi_lan_recv_packet(struct ipmi_intf * intf);
|
||||||
@ -227,7 +228,7 @@ struct ipmi_rs * ipmi_lan_recv_packet(struct ipmi_intf * intf)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
alarm(recv_timeout);
|
alarm(IPMI_LAN_TIMEOUT);
|
||||||
rc = recv(intf->fd, &rsp.data, BUF_SIZE, 0);
|
rc = recv(intf->fd, &rsp.data, BUF_SIZE, 0);
|
||||||
alarm(0);
|
alarm(0);
|
||||||
|
|
||||||
@ -242,7 +243,7 @@ struct ipmi_rs * ipmi_lan_recv_packet(struct ipmi_intf * intf)
|
|||||||
* response is read before the connection refused is returned)
|
* response is read before the connection refused is returned)
|
||||||
*/
|
*/
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
alarm(recv_timeout);
|
alarm(IPMI_LAN_TIMEOUT);
|
||||||
rc = recv(intf->fd, &rsp.data, BUF_SIZE, 0);
|
rc = recv(intf->fd, &rsp.data, BUF_SIZE, 0);
|
||||||
alarm(0);
|
alarm(0);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
@ -301,16 +302,14 @@ ipmi_handle_pong(struct ipmi_intf * intf, struct ipmi_rs * rsp)
|
|||||||
|
|
||||||
pong = (struct rmcp_pong *)rsp->data;
|
pong = (struct rmcp_pong *)rsp->data;
|
||||||
|
|
||||||
if (verbose)
|
|
||||||
printf("Received IPMI/RMCP response packet: "
|
|
||||||
"IPMI%s Supported\n",
|
|
||||||
(pong->sup_entities & 0x80) ? "" : " NOT");
|
|
||||||
|
|
||||||
if (verbose > 1)
|
if (verbose > 1)
|
||||||
printf(" ASF Version %s\n"
|
printf("Received IPMI/RMCP response packet: \n"
|
||||||
|
" IPMI%s Supported\n"
|
||||||
|
" ASF Version %s\n"
|
||||||
" RMCP Version %s\n"
|
" RMCP Version %s\n"
|
||||||
" RMCP Sequence %d\n"
|
" RMCP Sequence %d\n"
|
||||||
" IANA Enterprise %d\n\n",
|
" IANA Enterprise %d\n\n",
|
||||||
|
(pong->sup_entities & 0x80) ? "" : " NOT",
|
||||||
(pong->sup_entities & 0x01) ? "1.0" : "unknown",
|
(pong->sup_entities & 0x01) ? "1.0" : "unknown",
|
||||||
(pong->rmcp.ver == 6) ? "1.0" : "unknown",
|
(pong->rmcp.ver == 6) ? "1.0" : "unknown",
|
||||||
pong->rmcp.seq,
|
pong->rmcp.seq,
|
||||||
@ -359,7 +358,7 @@ ipmi_lan_ping(struct ipmi_intf * intf)
|
|||||||
memcpy(data, &rmcp_ping, sizeof(rmcp_ping));
|
memcpy(data, &rmcp_ping, sizeof(rmcp_ping));
|
||||||
memcpy(data+sizeof(rmcp_ping), &asf_ping, sizeof(asf_ping));
|
memcpy(data+sizeof(rmcp_ping), &asf_ping, sizeof(asf_ping));
|
||||||
|
|
||||||
if (verbose)
|
if (verbose > 1)
|
||||||
printf("Sending IPMI/RMCP presence ping packet\n");
|
printf("Sending IPMI/RMCP presence ping packet\n");
|
||||||
|
|
||||||
rv = ipmi_lan_send_packet(intf, data, len);
|
rv = ipmi_lan_send_packet(intf, data, len);
|
||||||
@ -398,7 +397,8 @@ ipmi_lan_pedantic(struct ipmi_intf * intf)
|
|||||||
* multi-session authcode generation for md5
|
* multi-session authcode generation for md5
|
||||||
* H(password + session_id + msg + session_seq + password)
|
* H(password + session_id + msg + session_seq + password)
|
||||||
*/
|
*/
|
||||||
unsigned char * ipmi_auth_md5(unsigned char * data, int data_len)
|
static unsigned char *
|
||||||
|
ipmi_auth_md5(struct ipmi_session * s, unsigned char * data, int data_len)
|
||||||
{
|
{
|
||||||
md5_state_t state;
|
md5_state_t state;
|
||||||
static md5_byte_t digest[16];
|
static md5_byte_t digest[16];
|
||||||
@ -409,17 +409,17 @@ unsigned char * ipmi_auth_md5(unsigned char * data, int data_len)
|
|||||||
|
|
||||||
md5_init(&state);
|
md5_init(&state);
|
||||||
|
|
||||||
md5_append(&state, (const md5_byte_t *)lan_session.authcode, 16);
|
md5_append(&state, (const md5_byte_t *)s->authcode, 16);
|
||||||
md5_append(&state, (const md5_byte_t *)&lan_session.id, 4);
|
md5_append(&state, (const md5_byte_t *)&s->session_id, 4);
|
||||||
md5_append(&state, (const md5_byte_t *)data, data_len);
|
md5_append(&state, (const md5_byte_t *)data, data_len);
|
||||||
|
|
||||||
#if WORDS_BIGENDIAN
|
#if WORDS_BIGENDIAN
|
||||||
temp = BSWAP_32(lan_session.in_seq);
|
temp = BSWAP_32(s->in_seq);
|
||||||
#else
|
#else
|
||||||
temp = lan_session.in_seq;
|
temp = s->in_seq;
|
||||||
#endif
|
#endif
|
||||||
md5_append(&state, (const md5_byte_t *)&temp, 4);
|
md5_append(&state, (const md5_byte_t *)&temp, 4);
|
||||||
md5_append(&state, (const md5_byte_t *)lan_session.authcode, 16);
|
md5_append(&state, (const md5_byte_t *)s->authcode, 16);
|
||||||
|
|
||||||
md5_finish(&state, digest);
|
md5_finish(&state, digest);
|
||||||
|
|
||||||
@ -464,13 +464,13 @@ ipmi_lan_poll_recv(struct ipmi_intf * intf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
x = 4;
|
x = 4;
|
||||||
rsp->session.authtype = rsp->data[x++];
|
rsp->session_hdr.authtype = rsp->data[x++];
|
||||||
memcpy(&rsp->session.seq, rsp->data+x, 4);
|
memcpy(&rsp->session_hdr.seq, rsp->data+x, 4);
|
||||||
x += 4;
|
x += 4;
|
||||||
memcpy(&rsp->session.id, rsp->data+x, 4);
|
memcpy(&rsp->session_hdr.id, rsp->data+x, 4);
|
||||||
x += 4;
|
x += 4;
|
||||||
|
|
||||||
if (lan_session.active && lan_session.authtype)
|
if (intf->session->active && intf->session->authtype)
|
||||||
x += 16;
|
x += 16;
|
||||||
|
|
||||||
rsp->msglen = rsp->data[x++];
|
rsp->msglen = rsp->data[x++];
|
||||||
@ -488,9 +488,9 @@ ipmi_lan_poll_recv(struct ipmi_intf * intf)
|
|||||||
printbuf(rsp->data, x, "ipmi message header");
|
printbuf(rsp->data, x, "ipmi message header");
|
||||||
printf("<< IPMI Response Session Header\n");
|
printf("<< IPMI Response Session Header\n");
|
||||||
printf("<< Authtype : %s\n",
|
printf("<< Authtype : %s\n",
|
||||||
val2str(rsp->session.authtype, ipmi_authtype_session_vals));
|
val2str(rsp->session_hdr.authtype, ipmi_authtype_session_vals));
|
||||||
printf("<< Sequence : 0x%08lx\n", rsp->session.seq);
|
printf("<< Sequence : 0x%08lx\n", rsp->session_hdr.seq);
|
||||||
printf("<< Session ID : 0x%08lx\n", rsp->session.id);
|
printf("<< Session ID : 0x%08lx\n", rsp->session_hdr.id);
|
||||||
|
|
||||||
printf("<< IPMI Response Message Header\n");
|
printf("<< IPMI Response Message Header\n");
|
||||||
printf("<< Rq Addr : %02x\n", rsp->header.rq_addr);
|
printf("<< Rq Addr : %02x\n", rsp->header.rq_addr);
|
||||||
@ -537,11 +537,11 @@ ipmi_lan_poll_recv(struct ipmi_intf * intf)
|
|||||||
* | rmcp.seq |
|
* | rmcp.seq |
|
||||||
* | rmcp.class |
|
* | rmcp.class |
|
||||||
* +--------------------+
|
* +--------------------+
|
||||||
* | session.authtype | 9 bytes
|
* | session_hdr.authtype | 9 bytes
|
||||||
* | session.seq |
|
* | session_hdr.seq |
|
||||||
* | session.id |
|
* | session_hdr.id |
|
||||||
* +--------------------+
|
* +--------------------+
|
||||||
* | [session.authcode] | 16 bytes (AUTHTYPE != none)
|
* | [session_hdr.authcode] | 16 bytes (AUTHTYPE != none)
|
||||||
* +--------------------+
|
* +--------------------+
|
||||||
* | message length | 1 byte
|
* | message length | 1 byte
|
||||||
* +--------------------+
|
* +--------------------+
|
||||||
@ -568,6 +568,8 @@ ipmi_lan_build_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
|
|||||||
unsigned char * msg;
|
unsigned char * msg;
|
||||||
int cs, mp, ap = 0, len = 0, tmp;
|
int cs, mp, ap = 0, len = 0, tmp;
|
||||||
struct ipmi_rq_entry * entry;
|
struct ipmi_rq_entry * entry;
|
||||||
|
struct ipmi_session * s = intf->session;
|
||||||
|
static curr_seq = 0;
|
||||||
|
|
||||||
if (curr_seq >= 64)
|
if (curr_seq >= 64)
|
||||||
curr_seq = 0;
|
curr_seq = 0;
|
||||||
@ -577,7 +579,6 @@ ipmi_lan_build_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
|
|||||||
memcpy(&entry->req, req, sizeof(struct ipmi_rq));
|
memcpy(&entry->req, req, sizeof(struct ipmi_rq));
|
||||||
|
|
||||||
entry->intf = intf;
|
entry->intf = intf;
|
||||||
entry->session = &lan_session;
|
|
||||||
|
|
||||||
if (!ipmi_req_entries) {
|
if (!ipmi_req_entries) {
|
||||||
ipmi_req_entries = entry;
|
ipmi_req_entries = entry;
|
||||||
@ -590,7 +591,7 @@ ipmi_lan_build_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
|
|||||||
curr_seq, req->msg.cmd);
|
curr_seq, req->msg.cmd);
|
||||||
|
|
||||||
len = req->msg.data_len + 21;
|
len = req->msg.data_len + 21;
|
||||||
if (lan_session.active && lan_session.authtype)
|
if (s->active && s->authtype)
|
||||||
len += 16;
|
len += 16;
|
||||||
msg = malloc(len);
|
msg = malloc(len);
|
||||||
memset(msg, 0, len);
|
memset(msg, 0, len);
|
||||||
@ -600,19 +601,19 @@ ipmi_lan_build_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
|
|||||||
len = sizeof(rmcp);
|
len = sizeof(rmcp);
|
||||||
|
|
||||||
/* ipmi session header */
|
/* ipmi session header */
|
||||||
msg[len++] = lan_session.active ? lan_session.authtype : 0;
|
msg[len++] = s->active ? s->authtype : 0;
|
||||||
|
|
||||||
msg[len++] = lan_session.in_seq & 0xff;
|
msg[len++] = s->in_seq & 0xff;
|
||||||
msg[len++] = (lan_session.in_seq >> 8) & 0xff;
|
msg[len++] = (s->in_seq >> 8) & 0xff;
|
||||||
msg[len++] = (lan_session.in_seq >> 16) & 0xff;
|
msg[len++] = (s->in_seq >> 16) & 0xff;
|
||||||
msg[len++] = (lan_session.in_seq >> 24) & 0xff;
|
msg[len++] = (s->in_seq >> 24) & 0xff;
|
||||||
memcpy(msg+len, &lan_session.id, 4);
|
memcpy(msg+len, &s->session_id, 4);
|
||||||
len += 4;
|
len += 4;
|
||||||
|
|
||||||
/* ipmi session authcode */
|
/* ipmi session authcode */
|
||||||
if (lan_session.active && lan_session.authtype) {
|
if (s->active && s->authtype) {
|
||||||
ap = len;
|
ap = len;
|
||||||
memcpy(msg+len, lan_session.authcode, 16);
|
memcpy(msg+len, s->authcode, 16);
|
||||||
len += 16;
|
len += 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -635,9 +636,9 @@ ipmi_lan_build_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
|
|||||||
if (verbose > 2) {
|
if (verbose > 2) {
|
||||||
printf(">> IPMI Request Session Header\n");
|
printf(">> IPMI Request Session Header\n");
|
||||||
printf(">> Authtype : %s\n",
|
printf(">> Authtype : %s\n",
|
||||||
val2str(lan_session.authtype, ipmi_authtype_session_vals));
|
val2str(s->authtype, ipmi_authtype_session_vals));
|
||||||
printf(">> Sequence : 0x%08lx\n", lan_session.in_seq);
|
printf(">> Sequence : 0x%08lx\n", s->in_seq);
|
||||||
printf(">> Session ID : 0x%08lx\n", lan_session.id);
|
printf(">> Session ID : 0x%08lx\n", s->session_id);
|
||||||
|
|
||||||
printf(">> IPMI Request Message Header\n");
|
printf(">> IPMI Request Message Header\n");
|
||||||
printf(">> Rs Addr : %02x\n", IPMI_BMC_SLAVE_ADDR);
|
printf(">> Rs Addr : %02x\n", IPMI_BMC_SLAVE_ADDR);
|
||||||
@ -659,16 +660,16 @@ ipmi_lan_build_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
|
|||||||
tmp = len - cs;
|
tmp = len - cs;
|
||||||
msg[len++] = ipmi_csum(msg+cs, tmp);
|
msg[len++] = ipmi_csum(msg+cs, tmp);
|
||||||
|
|
||||||
if (lan_session.active &&
|
if (s->active &&
|
||||||
lan_session.authtype == IPMI_SESSION_AUTHTYPE_MD5) {
|
s->authtype == IPMI_SESSION_AUTHTYPE_MD5) {
|
||||||
unsigned char * d = ipmi_auth_md5(msg+mp, msg[mp-1]);
|
unsigned char * d = ipmi_auth_md5(intf->session, msg+mp, msg[mp-1]);
|
||||||
memcpy(msg+ap, d, 16);
|
memcpy(msg+ap, d, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lan_session.in_seq) {
|
if (s->in_seq) {
|
||||||
lan_session.in_seq++;
|
s->in_seq++;
|
||||||
if (!lan_session.in_seq)
|
if (!s->in_seq)
|
||||||
lan_session.in_seq++;
|
s->in_seq++;
|
||||||
}
|
}
|
||||||
|
|
||||||
entry->msg_len = len;
|
entry->msg_len = len;
|
||||||
@ -684,6 +685,14 @@ ipmi_lan_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
|
|||||||
struct ipmi_rs * rsp;
|
struct ipmi_rs * rsp;
|
||||||
int try = 0;
|
int try = 0;
|
||||||
|
|
||||||
|
if (!intf->opened) {
|
||||||
|
intf->opened = 1;
|
||||||
|
if (intf->open(intf) < 0) {
|
||||||
|
intf->opened = 0;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
entry = ipmi_lan_build_cmd(intf, req);
|
entry = ipmi_lan_build_cmd(intf, req);
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
printf("Aborting send command, unable to build.\n");
|
printf("Aborting send command, unable to build.\n");
|
||||||
@ -692,8 +701,9 @@ ipmi_lan_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
|
|||||||
|
|
||||||
while (try < IPMI_LAN_RETRY) {
|
while (try < IPMI_LAN_RETRY) {
|
||||||
if (ipmi_lan_send_packet(intf, entry->msg_data, entry->msg_len) < 0) {
|
if (ipmi_lan_send_packet(intf, entry->msg_data, entry->msg_len) < 0) {
|
||||||
printf("ipmi_lan_send_cmd failed\n");
|
try++;
|
||||||
return NULL;
|
usleep(5000);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (intf->pedantic)
|
if (intf->pedantic)
|
||||||
@ -720,10 +730,11 @@ ipmi_get_auth_capabilities_cmd(struct ipmi_intf * intf)
|
|||||||
{
|
{
|
||||||
struct ipmi_rs * rsp;
|
struct ipmi_rs * rsp;
|
||||||
struct ipmi_rq req;
|
struct ipmi_rq req;
|
||||||
|
struct ipmi_session * s = intf->session;
|
||||||
unsigned char msg_data[2];
|
unsigned char msg_data[2];
|
||||||
|
|
||||||
msg_data[0] = IPMI_LAN_CHANNEL_E;
|
msg_data[0] = IPMI_LAN_CHANNEL_E;
|
||||||
msg_data[1] = lan_session.privlvl;
|
msg_data[1] = s->privlvl;
|
||||||
|
|
||||||
memset(&req, 0, sizeof(req));
|
memset(&req, 0, sizeof(req));
|
||||||
req.msg.netfn = IPMI_NETFN_APP;
|
req.msg.netfn = IPMI_NETFN_APP;
|
||||||
@ -775,16 +786,16 @@ ipmi_get_auth_capabilities_cmd(struct ipmi_intf * intf)
|
|||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lan_session.password &&
|
if (s->password &&
|
||||||
rsp->data[1] & 1<<IPMI_SESSION_AUTHTYPE_MD5) {
|
rsp->data[1] & 1<<IPMI_SESSION_AUTHTYPE_MD5) {
|
||||||
lan_session.authtype = IPMI_SESSION_AUTHTYPE_MD5;
|
s->authtype = IPMI_SESSION_AUTHTYPE_MD5;
|
||||||
}
|
}
|
||||||
else if (lan_session.password &&
|
else if (s->password &&
|
||||||
rsp->data[1] & 1<<IPMI_SESSION_AUTHTYPE_PASSWORD) {
|
rsp->data[1] & 1<<IPMI_SESSION_AUTHTYPE_PASSWORD) {
|
||||||
lan_session.authtype = IPMI_SESSION_AUTHTYPE_PASSWORD;
|
s->authtype = IPMI_SESSION_AUTHTYPE_PASSWORD;
|
||||||
}
|
}
|
||||||
else if (rsp->data[1] & 1<<IPMI_SESSION_AUTHTYPE_NONE) {
|
else if (rsp->data[1] & 1<<IPMI_SESSION_AUTHTYPE_NONE) {
|
||||||
lan_session.authtype = IPMI_SESSION_AUTHTYPE_NONE;
|
s->authtype = IPMI_SESSION_AUTHTYPE_NONE;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
printf("No supported authtypes found!\n");
|
printf("No supported authtypes found!\n");
|
||||||
@ -793,7 +804,7 @@ ipmi_get_auth_capabilities_cmd(struct ipmi_intf * intf)
|
|||||||
|
|
||||||
if (verbose > 1)
|
if (verbose > 1)
|
||||||
printf("Proceeding with AuthType %s\n",
|
printf("Proceeding with AuthType %s\n",
|
||||||
val2str(lan_session.authtype, ipmi_authtype_session_vals));
|
val2str(s->authtype, ipmi_authtype_session_vals));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -807,11 +818,12 @@ ipmi_get_session_challenge_cmd(struct ipmi_intf * intf)
|
|||||||
{
|
{
|
||||||
struct ipmi_rs * rsp;
|
struct ipmi_rs * rsp;
|
||||||
struct ipmi_rq req;
|
struct ipmi_rq req;
|
||||||
|
struct ipmi_session * s = intf->session;
|
||||||
unsigned char msg_data[17];
|
unsigned char msg_data[17];
|
||||||
|
|
||||||
memset(msg_data, 0, 17);
|
memset(msg_data, 0, 17);
|
||||||
msg_data[0] = lan_session.authtype;
|
msg_data[0] = s->authtype;
|
||||||
memcpy(msg_data+1, lan_session.username, 16);
|
memcpy(msg_data+1, s->username, 16);
|
||||||
|
|
||||||
memset(&req, 0, sizeof(req));
|
memset(&req, 0, sizeof(req));
|
||||||
req.msg.netfn = IPMI_NETFN_APP;
|
req.msg.netfn = IPMI_NETFN_APP;
|
||||||
@ -842,15 +854,15 @@ ipmi_get_session_challenge_cmd(struct ipmi_intf * intf)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(&lan_session.id, rsp->data, 4);
|
memcpy(&s->session_id, rsp->data, 4);
|
||||||
memcpy(lan_session.challenge, rsp->data + 4, 16);
|
memcpy(s->challenge, rsp->data + 4, 16);
|
||||||
|
|
||||||
if (verbose > 1) {
|
if (verbose > 1) {
|
||||||
printf("Opening Session\n");
|
printf("Opening Session\n");
|
||||||
printf(" Session ID : %08lx\n",
|
printf(" Session ID : %08lx\n",
|
||||||
lan_session.id);
|
s->session_id);
|
||||||
printf(" Challenge : %s\n",
|
printf(" Challenge : %s\n",
|
||||||
buf2str(lan_session.challenge, 16));
|
buf2str(s->challenge, 16));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -865,15 +877,16 @@ ipmi_activate_session_cmd(struct ipmi_intf * intf)
|
|||||||
{
|
{
|
||||||
struct ipmi_rs * rsp;
|
struct ipmi_rs * rsp;
|
||||||
struct ipmi_rq req;
|
struct ipmi_rq req;
|
||||||
|
struct ipmi_session * s = intf->session;
|
||||||
unsigned char msg_data[22];
|
unsigned char msg_data[22];
|
||||||
|
|
||||||
memset(&req, 0, sizeof(req));
|
memset(&req, 0, sizeof(req));
|
||||||
req.msg.netfn = IPMI_NETFN_APP;
|
req.msg.netfn = IPMI_NETFN_APP;
|
||||||
req.msg.cmd = 0x3a;
|
req.msg.cmd = 0x3a;
|
||||||
|
|
||||||
msg_data[0] = lan_session.authtype;
|
msg_data[0] = s->authtype;
|
||||||
msg_data[1] = lan_session.privlvl;
|
msg_data[1] = s->privlvl;
|
||||||
memcpy(msg_data + 2, lan_session.challenge, 16);
|
memcpy(msg_data + 2, s->challenge, 16);
|
||||||
|
|
||||||
/* setup initial outbound sequence number */
|
/* setup initial outbound sequence number */
|
||||||
get_random(msg_data+18, 4);
|
get_random(msg_data+18, 4);
|
||||||
@ -881,19 +894,19 @@ ipmi_activate_session_cmd(struct ipmi_intf * intf)
|
|||||||
req.msg.data = msg_data;
|
req.msg.data = msg_data;
|
||||||
req.msg.data_len = 22;
|
req.msg.data_len = 22;
|
||||||
|
|
||||||
lan_session.active = 1;
|
s->active = 1;
|
||||||
|
|
||||||
if (verbose > 1) {
|
if (verbose > 1) {
|
||||||
printf(" Privilege Level : %s\n",
|
printf(" Privilege Level : %s\n",
|
||||||
val2str(msg_data[1], ipmi_privlvl_vals));
|
val2str(msg_data[1], ipmi_privlvl_vals));
|
||||||
printf(" Auth Type : %s\n",
|
printf(" Auth Type : %s\n",
|
||||||
val2str(lan_session.authtype, ipmi_authtype_session_vals));
|
val2str(s->authtype, ipmi_authtype_session_vals));
|
||||||
}
|
}
|
||||||
|
|
||||||
rsp = intf->sendrecv(intf, &req);
|
rsp = intf->sendrecv(intf, &req);
|
||||||
if (!rsp) {
|
if (!rsp) {
|
||||||
printf("Error in Activate Session Command\n");
|
printf("Error in Activate Session Command\n");
|
||||||
lan_session.active = 0;
|
s->active = 0;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (verbose > 2)
|
if (verbose > 2)
|
||||||
@ -931,8 +944,8 @@ ipmi_activate_session_cmd(struct ipmi_intf * intf)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(&lan_session.id, rsp->data + 1, 4);
|
memcpy(&s->session_id, rsp->data + 1, 4);
|
||||||
lan_session.in_seq = rsp->data[8] << 24 | rsp->data[7] << 16 | rsp->data[6] << 8 | rsp->data[5];
|
s->in_seq = rsp->data[8] << 24 | rsp->data[7] << 16 | rsp->data[6] << 8 | rsp->data[5];
|
||||||
|
|
||||||
if (verbose > 1) {
|
if (verbose > 1) {
|
||||||
printf("\nSession Activated\n");
|
printf("\nSession Activated\n");
|
||||||
@ -940,14 +953,15 @@ ipmi_activate_session_cmd(struct ipmi_intf * intf)
|
|||||||
val2str(rsp->data[0], ipmi_authtype_session_vals));
|
val2str(rsp->data[0], ipmi_authtype_session_vals));
|
||||||
printf(" Max Priv Level : %s\n",
|
printf(" Max Priv Level : %s\n",
|
||||||
val2str(rsp->data[9], ipmi_privlvl_vals));
|
val2str(rsp->data[9], ipmi_privlvl_vals));
|
||||||
printf(" Session ID : %08lx\n", lan_session.id);
|
printf(" Session ID : %08lx\n", s->session_id);
|
||||||
printf(" Inbound Seq : %08lx\n", lan_session.in_seq);
|
printf(" Inbound Seq : %08lx\n", s->in_seq);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* IPMI Set Session Privilege Level Command
|
* IPMI Set Session Privilege Level Command
|
||||||
*/
|
*/
|
||||||
@ -956,11 +970,12 @@ ipmi_set_session_privlvl_cmd(struct ipmi_intf * intf)
|
|||||||
{
|
{
|
||||||
struct ipmi_rs * rsp;
|
struct ipmi_rs * rsp;
|
||||||
struct ipmi_rq req;
|
struct ipmi_rq req;
|
||||||
|
unsigned char privlvl = intf->session->privlvl;
|
||||||
|
|
||||||
memset(&req, 0, sizeof(req));
|
memset(&req, 0, sizeof(req));
|
||||||
req.msg.netfn = IPMI_NETFN_APP;
|
req.msg.netfn = IPMI_NETFN_APP;
|
||||||
req.msg.cmd = 0x3b;
|
req.msg.cmd = 0x3b;
|
||||||
req.msg.data = &lan_session.privlvl;
|
req.msg.data = &privlvl;
|
||||||
req.msg.data_len = 1;
|
req.msg.data_len = 1;
|
||||||
|
|
||||||
rsp = intf->sendrecv(intf, &req);
|
rsp = intf->sendrecv(intf, &req);
|
||||||
@ -973,7 +988,7 @@ ipmi_set_session_privlvl_cmd(struct ipmi_intf * intf)
|
|||||||
|
|
||||||
if (rsp->ccode) {
|
if (rsp->ccode) {
|
||||||
printf("Failed to set session privilege level to %s\n\n",
|
printf("Failed to set session privilege level to %s\n\n",
|
||||||
val2str(lan_session.privlvl, ipmi_privlvl_vals));
|
val2str(privlvl, ipmi_privlvl_vals));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (verbose > 1)
|
if (verbose > 1)
|
||||||
@ -988,11 +1003,12 @@ impi_close_session_cmd(struct ipmi_intf * intf)
|
|||||||
struct ipmi_rs * rsp;
|
struct ipmi_rs * rsp;
|
||||||
struct ipmi_rq req;
|
struct ipmi_rq req;
|
||||||
unsigned char msg_data[4];
|
unsigned char msg_data[4];
|
||||||
|
uint32_t session_id = intf->session->session_id;
|
||||||
|
|
||||||
if (!lan_session.active)
|
if (!intf->session->active)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
memcpy(&msg_data, &lan_session.id, 4);
|
memcpy(&msg_data, &session_id, 4);
|
||||||
|
|
||||||
memset(&req, 0, sizeof(req));
|
memset(&req, 0, sizeof(req));
|
||||||
req.msg.netfn = IPMI_NETFN_APP;
|
req.msg.netfn = IPMI_NETFN_APP;
|
||||||
@ -1010,7 +1026,7 @@ impi_close_session_cmd(struct ipmi_intf * intf)
|
|||||||
|
|
||||||
if (rsp->ccode == 0x87) {
|
if (rsp->ccode == 0x87) {
|
||||||
printf("Failed to Close Session: invalid session ID %08lx\n",
|
printf("Failed to Close Session: invalid session ID %08lx\n",
|
||||||
lan_session.id);
|
session_id);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (rsp->ccode) {
|
if (rsp->ccode) {
|
||||||
@ -1019,7 +1035,7 @@ impi_close_session_cmd(struct ipmi_intf * intf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (verbose > 1)
|
if (verbose > 1)
|
||||||
printf("\nClosed Session %08lx\n\n", lan_session.id);
|
printf("\nClosed Session %08lx\n\n", session_id);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1046,14 +1062,14 @@ ipmi_lan_activate_session(struct ipmi_intf * intf)
|
|||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/*
|
/* don't fail on ping because its not always supported */
|
||||||
rc = ipmi_lan_ping(intf);
|
rc = ipmi_lan_ping(intf);
|
||||||
if (rc <= 0) {
|
if (rc <= 0) {
|
||||||
printf("IPMI not supported!\n");
|
if (verbose > 1)
|
||||||
return -1;
|
printf("RMCP Pong : IPMI not supported!\n");
|
||||||
|
/* send again */
|
||||||
|
ipmi_lan_ping(intf);
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
lan_session.privlvl = IPMI_SESSION_PRIV_ADMIN;
|
|
||||||
|
|
||||||
if (intf->pedantic)
|
if (intf->pedantic)
|
||||||
ipmi_lan_first(intf);
|
ipmi_lan_first(intf);
|
||||||
@ -1091,59 +1107,57 @@ void ipmi_lan_close(struct ipmi_intf * intf)
|
|||||||
{
|
{
|
||||||
if (!intf->abort)
|
if (!intf->abort)
|
||||||
impi_close_session_cmd(intf);
|
impi_close_session_cmd(intf);
|
||||||
close(intf->fd);
|
if (intf->fd >= 0)
|
||||||
|
close(intf->fd);
|
||||||
ipmi_req_clear_entries();
|
ipmi_req_clear_entries();
|
||||||
|
if (intf->session)
|
||||||
|
free(intf->session);
|
||||||
|
intf->session = NULL;
|
||||||
|
intf = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ipmi_lan_open(struct ipmi_intf * intf, char * hostname, int port, char * username, char * password)
|
int ipmi_lan_open(struct ipmi_intf * intf)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
struct sigaction act;
|
struct sigaction act;
|
||||||
|
struct sockaddr_in addr;
|
||||||
|
struct ipmi_session *s;
|
||||||
|
|
||||||
if (!intf)
|
if (!intf || !intf->session)
|
||||||
return -1;
|
return -1;
|
||||||
|
s = intf->session;
|
||||||
|
|
||||||
if (intf->pedantic)
|
if (!s->port)
|
||||||
recv_timeout = 3;
|
s->port = IPMI_LAN_PORT;
|
||||||
|
if (!s->privlvl)
|
||||||
|
s->privlvl = IPMI_SESSION_PRIV_USER;
|
||||||
|
|
||||||
if (!hostname) {
|
if (!s->hostname) {
|
||||||
printf("No hostname specified!\n");
|
printf("No hostname specified!\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&lan_session, 0, sizeof(lan_session));
|
|
||||||
curr_seq = 0;
|
|
||||||
|
|
||||||
if (username) {
|
|
||||||
memcpy(lan_session.username, username, strlen(username));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (password) {
|
|
||||||
lan_session.password = 1;
|
|
||||||
memcpy(lan_session.authcode, password, strlen(password));
|
|
||||||
}
|
|
||||||
|
|
||||||
intf->abort = 1;
|
intf->abort = 1;
|
||||||
|
|
||||||
/* open port to BMC */
|
/* open port to BMC */
|
||||||
memset(&intf->addr, 0, sizeof(struct sockaddr_in));
|
memset(&addr, 0, sizeof(struct sockaddr_in));
|
||||||
intf->addr.sin_family = AF_INET;
|
addr.sin_family = AF_INET;
|
||||||
intf->addr.sin_port = htons(port);
|
addr.sin_port = htons(s->port);
|
||||||
|
|
||||||
rc = inet_pton(AF_INET, hostname, &intf->addr.sin_addr);
|
rc = inet_pton(AF_INET, s->hostname, &addr.sin_addr);
|
||||||
if (rc <= 0) {
|
if (rc <= 0) {
|
||||||
struct hostent *host = gethostbyname(hostname);
|
struct hostent *host = gethostbyname(s->hostname);
|
||||||
if (!host) {
|
if (!host) {
|
||||||
printf("address lookup failed\n");
|
printf("address lookup failed\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
intf->addr.sin_family = host->h_addrtype;
|
addr.sin_family = host->h_addrtype;
|
||||||
memcpy(&intf->addr.sin_addr, host->h_addr, host->h_length);
|
memcpy(&addr.sin_addr, host->h_addr, host->h_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verbose > 1)
|
if (verbose > 1)
|
||||||
printf("IPMI LAN host %s port %d\n",
|
printf("IPMI LAN host %s port %d\n",
|
||||||
hostname, ntohs(intf->addr.sin_port));
|
s->hostname, ntohs(addr.sin_port));
|
||||||
|
|
||||||
intf->fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
intf->fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
if (intf->fd < 0) {
|
if (intf->fd < 0) {
|
||||||
@ -1152,7 +1166,7 @@ int ipmi_lan_open(struct ipmi_intf * intf, char * hostname, int port, char * use
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* connect to UDP socket so we get async errors */
|
/* connect to UDP socket so we get async errors */
|
||||||
rc = connect(intf->fd, (struct sockaddr *)&intf->addr, sizeof(intf->addr));
|
rc = connect(intf->fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
perror("connect failed");
|
perror("connect failed");
|
||||||
intf->close(intf);
|
intf->close(intf);
|
||||||
@ -1181,7 +1195,9 @@ int ipmi_lan_open(struct ipmi_intf * intf, char * hostname, int port, char * use
|
|||||||
int lan_intf_setup(struct ipmi_intf ** intf)
|
int lan_intf_setup(struct ipmi_intf ** intf)
|
||||||
{
|
{
|
||||||
*intf = &ipmi_lan_intf;
|
*intf = &ipmi_lan_intf;
|
||||||
return 0;
|
(*intf)->session = malloc(sizeof(struct ipmi_session));
|
||||||
|
memset((*intf)->session, 0, sizeof(struct ipmi_session));
|
||||||
|
return ((*intf)->session) ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int intf_setup(struct ipmi_intf ** intf) __attribute__ ((weak, alias("lan_intf_setup")));
|
int intf_setup(struct ipmi_intf ** intf) __attribute__ ((weak, alias("lan_intf_setup")));
|
||||||
|
@ -38,10 +38,12 @@
|
|||||||
#define IPMI_LAN_H
|
#define IPMI_LAN_H
|
||||||
|
|
||||||
#include <ipmitool/ipmi.h>
|
#include <ipmitool/ipmi.h>
|
||||||
|
#include <ipmitool/ipmi_intf.h>
|
||||||
|
|
||||||
#define IPMI_LAN_CHANNEL_1 0x07
|
#define IPMI_LAN_CHANNEL_1 0x07
|
||||||
#define IPMI_LAN_CHANNEL_2 0x06
|
#define IPMI_LAN_CHANNEL_2 0x06
|
||||||
#define IPMI_LAN_CHANNEL_E 0x0e
|
#define IPMI_LAN_CHANNEL_E 0x0e
|
||||||
|
#define IPMI_LAN_PORT 0x26f
|
||||||
|
|
||||||
#define IPMI_LAN_TIMEOUT 2
|
#define IPMI_LAN_TIMEOUT 2
|
||||||
#define IPMI_LAN_RETRY 4
|
#define IPMI_LAN_RETRY 4
|
||||||
@ -58,15 +60,10 @@
|
|||||||
#define IPMI_SESSION_PRIV_ADMIN 0x4
|
#define IPMI_SESSION_PRIV_ADMIN 0x4
|
||||||
#define IPMI_SESSION_PRIV_OEM 0x5
|
#define IPMI_SESSION_PRIV_OEM 0x5
|
||||||
|
|
||||||
extern const struct valstr ipmi_privlvl_vals[];
|
|
||||||
extern const struct valstr ipmi_authtype_vals[];
|
|
||||||
|
|
||||||
extern struct ipmi_session lan_session;
|
|
||||||
unsigned char * ipmi_auth_md5(unsigned char * data, int data_len);
|
|
||||||
unsigned char ipmi_csum(unsigned char * d, int s);
|
unsigned char ipmi_csum(unsigned char * d, int s);
|
||||||
|
|
||||||
struct ipmi_rs * ipmi_lan_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req);
|
struct ipmi_rs * ipmi_lan_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req);
|
||||||
int ipmi_lan_open(struct ipmi_intf * intf, char * hostname, int port, char * username, char * password);
|
int ipmi_lan_open(struct ipmi_intf * intf);
|
||||||
void ipmi_lan_close(struct ipmi_intf * intf);
|
void ipmi_lan_close(struct ipmi_intf * intf);
|
||||||
void ipmi_get_channel_info(struct ipmi_intf * intf, unsigned char channel);
|
void ipmi_get_channel_info(struct ipmi_intf * intf, unsigned char channel);
|
||||||
int ipmi_lan_ping(struct ipmi_intf * intf);
|
int ipmi_lan_ping(struct ipmi_intf * intf);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user