mirror of
https://github.com/ipmitool/ipmitool.git
synced 2025-07-02 18:53:45 +00:00
- remove dynamic interface support
- support for bridged IPMB messages - add function to build/send IPMI response messages - fix reporting of "per-msg-auth" and "user-level-auth" during Get Channel Authentication Capabilities phase
This commit is contained in:
@ -85,11 +85,17 @@ static sigjmp_buf jmpbuf;
|
|||||||
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);
|
||||||
static struct ipmi_rs * ipmi_lan_poll_recv(struct ipmi_intf * intf);
|
static struct ipmi_rs * ipmi_lan_poll_recv(struct ipmi_intf * intf);
|
||||||
|
static int ipmi_lan_setup(struct ipmi_intf * intf);
|
||||||
|
|
||||||
struct ipmi_intf ipmi_lan_intf = {
|
struct ipmi_intf ipmi_lan_intf = {
|
||||||
.open = ipmi_lan_open,
|
name: "lan",
|
||||||
.close = ipmi_lan_close,
|
desc: "IPMI v1.5 LAN Interface",
|
||||||
.sendrecv = ipmi_lan_send_cmd,
|
setup: ipmi_lan_setup,
|
||||||
|
open: ipmi_lan_open,
|
||||||
|
close: ipmi_lan_close,
|
||||||
|
sendrecv: ipmi_lan_send_cmd,
|
||||||
|
sendrsp: ipmi_lan_send_rsp,
|
||||||
|
target_addr: IPMI_BMC_SLAVE_ADDR,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -133,6 +139,32 @@ static const struct valstr ipmi_channel_medium_vals[] = {
|
|||||||
{ 0x00, NULL },
|
{ 0x00, NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct ipmi_rq_entry *
|
||||||
|
ipmi_req_add_entry(struct ipmi_intf * intf, struct ipmi_rq * req)
|
||||||
|
{
|
||||||
|
struct ipmi_rq_entry * e = malloc(sizeof(struct ipmi_rq_entry));
|
||||||
|
|
||||||
|
if (e == NULL)
|
||||||
|
printf("WARNING: no memory!\n");
|
||||||
|
else {
|
||||||
|
memset(e, 0, sizeof(struct ipmi_rq_entry));
|
||||||
|
memcpy(&e->req, req, sizeof(struct ipmi_rq));
|
||||||
|
|
||||||
|
e->intf = intf;
|
||||||
|
|
||||||
|
if (!ipmi_req_entries) {
|
||||||
|
ipmi_req_entries = e;
|
||||||
|
} else {
|
||||||
|
ipmi_req_entries_tail->next = e;
|
||||||
|
}
|
||||||
|
ipmi_req_entries_tail = e;
|
||||||
|
if (verbose > 3)
|
||||||
|
printf("added list entry seq=0x%02x cmd=0x%02x\n",
|
||||||
|
e->rq_seq, e->req.msg.cmd);
|
||||||
|
}
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
static struct ipmi_rq_entry *
|
static struct ipmi_rq_entry *
|
||||||
ipmi_req_lookup_entry(unsigned char seq, unsigned char cmd)
|
ipmi_req_lookup_entry(unsigned char seq, unsigned char cmd)
|
||||||
{
|
{
|
||||||
@ -376,21 +408,21 @@ ipmi_lan_ping(struct ipmi_intf * intf)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* special packet, no idea what it does */
|
/*
|
||||||
ipmi_lan_first(struct ipmi_intf * intf)
|
* The "thump" functions are used to send an extra packet following each
|
||||||
|
* request message. This may kick-start some BMCs that get confused with
|
||||||
|
* bad passwords or operate poorly under heavy network load.
|
||||||
|
*/
|
||||||
|
static void ipmi_lan_thump_first(struct ipmi_intf * intf)
|
||||||
{
|
{
|
||||||
unsigned char data[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
unsigned char data[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x07, 0x20, 0x18, 0xc8, 0xc2, 0x01, 0x01, 0x3c };
|
0x07, 0x20, 0x18, 0xc8, 0xc2, 0x01, 0x01, 0x3c };
|
||||||
ipmi_lan_send_packet(intf, data, 16);
|
ipmi_lan_send_packet(intf, data, 16);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
static void ipmi_lan_thump(struct ipmi_intf * intf)
|
||||||
static int
|
|
||||||
ipmi_lan_pedantic(struct ipmi_intf * intf)
|
|
||||||
{
|
{
|
||||||
unsigned char data[10] = "dummy";
|
unsigned char data[10] = "thump";
|
||||||
ipmi_lan_send_packet(intf, data, 10);
|
ipmi_lan_send_packet(intf, data, 10);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -496,14 +528,21 @@ ipmi_lan_poll_recv(struct ipmi_intf * intf)
|
|||||||
printf("<< Compl Code : 0x%02x\n", rsp->ccode);
|
printf("<< Compl Code : 0x%02x\n", rsp->ccode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* now see if we have oustanding entry in request list */
|
/* now see if we have outstanding entry in request list */
|
||||||
entry = ipmi_req_lookup_entry(rsp->payload.ipmi_response.rq_seq,
|
entry = ipmi_req_lookup_entry(rsp->payload.ipmi_response.rq_seq,
|
||||||
rsp->payload.ipmi_response.cmd);
|
rsp->payload.ipmi_response.cmd);
|
||||||
if (entry) {
|
if (entry) {
|
||||||
if (verbose > 2)
|
if (verbose > 2)
|
||||||
printf("IPMI Request Match found\n");
|
printf("IPMI Request Match found\n");
|
||||||
|
if (intf->target_addr != IPMI_BMC_SLAVE_ADDR) {
|
||||||
|
/* bridged command: lose extra header */
|
||||||
|
x += sizeof(rsp->payload.ipmi_response);
|
||||||
|
if (verbose && rsp->data[x-1] != 0)
|
||||||
|
printf("WARNING: Bridged cmd ccode = 0x%02x\n",
|
||||||
|
rsp->data[x-1]);
|
||||||
|
}
|
||||||
ipmi_req_remove_entry(rsp->payload.ipmi_response.rq_seq,
|
ipmi_req_remove_entry(rsp->payload.ipmi_response.rq_seq,
|
||||||
rsp->payload.ipmi_response.cmd);
|
rsp->payload.ipmi_response.cmd);
|
||||||
} else {
|
} else {
|
||||||
if (verbose)
|
if (verbose)
|
||||||
printf("WARNING: IPMI Request Match NOT FOUND!\n");
|
printf("WARNING: IPMI Request Match NOT FOUND!\n");
|
||||||
@ -561,7 +600,9 @@ ipmi_lan_build_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
|
|||||||
.seq = 0xff,
|
.seq = 0xff,
|
||||||
};
|
};
|
||||||
unsigned char * msg;
|
unsigned char * msg;
|
||||||
int cs, mp, ap = 0, len = 0, tmp;
|
int cs, cs2, mp, tmp;
|
||||||
|
int ap = 0;
|
||||||
|
int len = 0;
|
||||||
struct ipmi_rq_entry * entry;
|
struct ipmi_rq_entry * entry;
|
||||||
struct ipmi_session * s = intf->session;
|
struct ipmi_session * s = intf->session;
|
||||||
static curr_seq = 0;
|
static curr_seq = 0;
|
||||||
@ -569,23 +610,11 @@ ipmi_lan_build_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
|
|||||||
if (curr_seq >= 64)
|
if (curr_seq >= 64)
|
||||||
curr_seq = 0;
|
curr_seq = 0;
|
||||||
|
|
||||||
entry = malloc(sizeof(struct ipmi_rq_entry));
|
entry = ipmi_req_add_entry(intf, req);
|
||||||
memset(entry, 0, sizeof(struct ipmi_rq_entry));
|
if (!entry)
|
||||||
memcpy(&entry->req, req, sizeof(struct ipmi_rq));
|
return NULL;
|
||||||
|
|
||||||
entry->intf = intf;
|
|
||||||
|
|
||||||
if (!ipmi_req_entries) {
|
|
||||||
ipmi_req_entries = entry;
|
|
||||||
} else {
|
|
||||||
ipmi_req_entries_tail->next = entry;
|
|
||||||
}
|
|
||||||
ipmi_req_entries_tail = entry;
|
|
||||||
if (verbose > 3)
|
|
||||||
printf("added list entry seq=0x%02x cmd=0x%02x\n",
|
|
||||||
curr_seq, req->msg.cmd);
|
|
||||||
|
|
||||||
len = req->msg.data_len + 21;
|
len = req->msg.data_len + 29;
|
||||||
if (s->active && s->authtype)
|
if (s->active && s->authtype)
|
||||||
len += 16;
|
len += 16;
|
||||||
msg = malloc(len);
|
msg = malloc(len);
|
||||||
@ -613,11 +642,29 @@ ipmi_lan_build_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* message length */
|
/* message length */
|
||||||
msg[len++] = req->msg.data_len + 7;
|
if (intf->target_addr == IPMI_BMC_SLAVE_ADDR) {
|
||||||
|
msg[len++] = req->msg.data_len + 7;
|
||||||
|
cs = mp = len;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* bridged request: encapsulate w/in Send Message */
|
||||||
|
msg[len++] = req->msg.data_len + 15;
|
||||||
|
cs = mp = len;
|
||||||
|
msg[len++] = IPMI_BMC_SLAVE_ADDR;
|
||||||
|
msg[len++] = IPMI_NETFN_APP << 2;
|
||||||
|
tmp = len - cs;
|
||||||
|
msg[len++] = ipmi_csum(msg+cs, tmp);
|
||||||
|
cs2 = len;
|
||||||
|
msg[len++] = IPMI_REMOTE_SWID;
|
||||||
|
msg[len++] = curr_seq << 2;
|
||||||
|
msg[len++] = 0x34; /* Send Message rqst */
|
||||||
|
entry->req.msg.cmd = 0x34; /* (fixup request entry) */
|
||||||
|
msg[len++] = 0x40; /* Track request, Channel=IPMB */
|
||||||
|
cs = len;
|
||||||
|
}
|
||||||
|
|
||||||
/* ipmi message header */
|
/* ipmi message header */
|
||||||
cs = mp = len;
|
msg[len++] = intf->target_addr;
|
||||||
msg[len++] = IPMI_BMC_SLAVE_ADDR;
|
|
||||||
msg[len++] = req->msg.netfn << 2;
|
msg[len++] = req->msg.netfn << 2;
|
||||||
tmp = len - cs;
|
tmp = len - cs;
|
||||||
msg[len++] = ipmi_csum(msg+cs, tmp);
|
msg[len++] = ipmi_csum(msg+cs, tmp);
|
||||||
@ -636,7 +683,7 @@ ipmi_lan_build_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
|
|||||||
printf(">> Session ID : 0x%08lx\n", s->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", intf->target_addr);
|
||||||
printf(">> NetFn : %02x\n", req->msg.netfn);
|
printf(">> NetFn : %02x\n", req->msg.netfn);
|
||||||
printf(">> Rs LUN : %01x\n", 0);
|
printf(">> Rs LUN : %01x\n", 0);
|
||||||
printf(">> Rq Addr : %02x\n", IPMI_REMOTE_SWID);
|
printf(">> Rq Addr : %02x\n", IPMI_REMOTE_SWID);
|
||||||
@ -647,7 +694,7 @@ ipmi_lan_build_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
|
|||||||
|
|
||||||
/* message data */
|
/* message data */
|
||||||
if (req->msg.data_len) {
|
if (req->msg.data_len) {
|
||||||
memcpy(msg+len, req->msg.data, req->msg.data_len);
|
memcpy(msg+len, req->msg.data, req->msg.data_len);
|
||||||
len += req->msg.data_len;
|
len += req->msg.data_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -655,6 +702,12 @@ 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);
|
||||||
|
|
||||||
|
/* bridged request: 2nd checksum */
|
||||||
|
if (intf->target_addr != IPMI_BMC_SLAVE_ADDR) {
|
||||||
|
tmp = len - cs2;
|
||||||
|
msg[len++] = ipmi_csum(msg+cs2, tmp);
|
||||||
|
}
|
||||||
|
|
||||||
if (s->active &&
|
if (s->active &&
|
||||||
s->authtype == IPMI_SESSION_AUTHTYPE_MD5) {
|
s->authtype == IPMI_SESSION_AUTHTYPE_MD5) {
|
||||||
unsigned char * d = ipmi_auth_md5(intf->session, msg+mp, msg[mp-1]);
|
unsigned char * d = ipmi_auth_md5(intf->session, msg+mp, msg[mp-1]);
|
||||||
@ -680,13 +733,8 @@ 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) {
|
if (!intf->opened && intf->open && intf->open(intf) < 0)
|
||||||
intf->opened = 1;
|
return NULL;
|
||||||
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) {
|
||||||
@ -694,15 +742,15 @@ ipmi_lan_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (try < IPMI_LAN_RETRY) {
|
for (;;) {
|
||||||
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) {
|
||||||
try++;
|
try++;
|
||||||
usleep(5000);
|
usleep(5000);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (intf->pedantic)
|
if (intf->thump)
|
||||||
ipmi_lan_pedantic(intf);
|
ipmi_lan_thump(intf);
|
||||||
|
|
||||||
usleep(100);
|
usleep(100);
|
||||||
|
|
||||||
@ -711,12 +759,123 @@ ipmi_lan_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
usleep(5000);
|
usleep(5000);
|
||||||
try++;
|
if (++try >= IPMI_LAN_RETRY) {
|
||||||
|
if (verbose)
|
||||||
|
printf(" No response.\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return rsp;
|
return rsp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned char * ipmi_lan_build_rsp(struct ipmi_intf * intf, struct ipmi_rs * rsp, int * llen)
|
||||||
|
{
|
||||||
|
struct rmcp_hdr rmcp = {
|
||||||
|
.ver = RMCP_VERSION_1,
|
||||||
|
.class = RMCP_CLASS_IPMI,
|
||||||
|
.seq = 0xff,
|
||||||
|
};
|
||||||
|
int cs, mp, ap = 0, tmp, rv;
|
||||||
|
int len;
|
||||||
|
unsigned char * msg;
|
||||||
|
|
||||||
|
len = rsp->data_len + 22;
|
||||||
|
if (intf->session->active && intf->session->authtype)
|
||||||
|
len += 16;
|
||||||
|
|
||||||
|
msg = malloc(len);
|
||||||
|
memset(msg, 0, len);
|
||||||
|
|
||||||
|
/* rmcp header */
|
||||||
|
memcpy(msg, &rmcp, 4);
|
||||||
|
len = sizeof(rmcp);
|
||||||
|
|
||||||
|
/* ipmi session header */
|
||||||
|
msg[len++] = intf->session->active ? intf->session->authtype : 0;
|
||||||
|
|
||||||
|
if (intf->session->in_seq) {
|
||||||
|
intf->session->in_seq++;
|
||||||
|
if (!intf->session->in_seq)
|
||||||
|
intf->session->in_seq++;
|
||||||
|
}
|
||||||
|
memcpy(msg+len, &intf->session->in_seq, 4);
|
||||||
|
len += 4;
|
||||||
|
memcpy(msg+len, &intf->session->session_id, 4);
|
||||||
|
len += 4;
|
||||||
|
|
||||||
|
/* session authcode, if session active and authtype is not none */
|
||||||
|
if (intf->session->active && intf->session->authtype) {
|
||||||
|
ap = len;
|
||||||
|
memcpy(msg+len, intf->session->authcode, 16);
|
||||||
|
len += 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* message length */
|
||||||
|
msg[len++] = rsp->data_len + 8;
|
||||||
|
|
||||||
|
/* message header */
|
||||||
|
cs = mp = len;
|
||||||
|
msg[len++] = IPMI_REMOTE_SWID;
|
||||||
|
msg[len++] = rsp->msg.netfn << 2;
|
||||||
|
tmp = len - cs;
|
||||||
|
msg[len++] = ipmi_csum(msg+cs, tmp);
|
||||||
|
cs = len;
|
||||||
|
msg[len++] = IPMI_BMC_SLAVE_ADDR;
|
||||||
|
msg[len++] = (rsp->msg.seq << 2) | (rsp->msg.lun & 3);
|
||||||
|
msg[len++] = rsp->msg.cmd;
|
||||||
|
|
||||||
|
/* completion code */
|
||||||
|
msg[len++] = rsp->ccode;
|
||||||
|
|
||||||
|
/* message data */
|
||||||
|
if (rsp->data_len) {
|
||||||
|
memcpy(msg+len, rsp->data, rsp->data_len);
|
||||||
|
len += rsp->data_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* second checksum */
|
||||||
|
tmp = len - cs;
|
||||||
|
msg[len++] = ipmi_csum(msg+cs, tmp);
|
||||||
|
|
||||||
|
if (intf->session->active &&
|
||||||
|
intf->session->authtype == IPMI_SESSION_AUTHTYPE_MD5) {
|
||||||
|
unsigned char * d = ipmi_auth_md5(intf->session, msg+mp, msg[mp-1]);
|
||||||
|
memcpy(msg+ap, d, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
*llen = len;
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ipmi_lan_send_rsp(struct ipmi_intf * intf, struct ipmi_rs * rsp)
|
||||||
|
{
|
||||||
|
unsigned char * msg;
|
||||||
|
int len, rv;
|
||||||
|
|
||||||
|
msg = ipmi_lan_build_rsp(intf, rsp, &len);
|
||||||
|
if (len <= 0 || !msg) {
|
||||||
|
printf("ipmi_lan_send_rsp: invalid response packet\n");
|
||||||
|
if (msg)
|
||||||
|
free(msg);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = sendto(intf->fd, msg, len, 0,
|
||||||
|
(struct sockaddr *)&intf->session->addr,
|
||||||
|
intf->session->addrlen);
|
||||||
|
if (rv < 0) {
|
||||||
|
printf("ipmi_lan_send_rsp: packet send failed\n");
|
||||||
|
if (msg)
|
||||||
|
free(msg);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msg)
|
||||||
|
free(msg);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* IPMI Get Channel Authentication Capabilities Command
|
* IPMI Get Channel Authentication Capabilities Command
|
||||||
*/
|
*/
|
||||||
@ -769,9 +928,9 @@ ipmi_get_auth_capabilities_cmd(struct ipmi_intf * intf)
|
|||||||
printf("OEM ");
|
printf("OEM ");
|
||||||
printf("\n");
|
printf("\n");
|
||||||
printf(" Per-msg auth : %sabled\n",
|
printf(" Per-msg auth : %sabled\n",
|
||||||
(rsp->data[2] & 1<<4) ? "en" : "dis");
|
(rsp->data[2] & 1<<4) ? "dis" : "en");
|
||||||
printf(" User level auth : %sabled\n",
|
printf(" User level auth : %sabled\n",
|
||||||
(rsp->data[2] & 1<<3) ? "en" : "dis");
|
(rsp->data[2] & 1<<3) ? "dis" : "en");
|
||||||
printf(" Non-null users : %sabled\n",
|
printf(" Non-null users : %sabled\n",
|
||||||
(rsp->data[2] & 1<<2) ? "en" : "dis");
|
(rsp->data[2] & 1<<2) ? "en" : "dis");
|
||||||
printf(" Null users : %sabled\n",
|
printf(" Null users : %sabled\n",
|
||||||
@ -941,6 +1100,7 @@ ipmi_activate_session_cmd(struct ipmi_intf * intf)
|
|||||||
|
|
||||||
memcpy(&s->session_id, rsp->data + 1, 4);
|
memcpy(&s->session_id, rsp->data + 1, 4);
|
||||||
s->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];
|
||||||
|
s->authtype = rsp->data[0] & 0xf;
|
||||||
|
|
||||||
if (verbose > 1) {
|
if (verbose > 1) {
|
||||||
printf("\nSession Activated\n");
|
printf("\nSession Activated\n");
|
||||||
@ -967,6 +1127,9 @@ ipmi_set_session_privlvl_cmd(struct ipmi_intf * intf)
|
|||||||
struct ipmi_rq req;
|
struct ipmi_rq req;
|
||||||
unsigned char privlvl = intf->session->privlvl;
|
unsigned char privlvl = intf->session->privlvl;
|
||||||
|
|
||||||
|
if (privlvl <= IPMI_SESSION_PRIV_USER)
|
||||||
|
return 0; /* no need to set higher */
|
||||||
|
|
||||||
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;
|
||||||
@ -1003,6 +1166,8 @@ impi_close_session_cmd(struct ipmi_intf * intf)
|
|||||||
if (!intf->session->active)
|
if (!intf->session->active)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
intf->target_addr = IPMI_BMC_SLAVE_ADDR;
|
||||||
|
|
||||||
memcpy(&msg_data, &session_id, 4);
|
memcpy(&msg_data, &session_id, 4);
|
||||||
|
|
||||||
memset(&req, 0, sizeof(req));
|
memset(&req, 0, sizeof(req));
|
||||||
@ -1060,8 +1225,8 @@ ipmi_lan_activate_session(struct ipmi_intf * intf)
|
|||||||
/* don't fail on ping because its not always supported */
|
/* don't fail on ping because its not always supported */
|
||||||
ipmi_lan_ping(intf);
|
ipmi_lan_ping(intf);
|
||||||
|
|
||||||
if (intf->pedantic)
|
if (intf->thump)
|
||||||
ipmi_lan_first(intf);
|
ipmi_lan_thump_first(intf);
|
||||||
|
|
||||||
rc = ipmi_get_auth_capabilities_cmd(intf);
|
rc = ipmi_get_auth_capabilities_cmd(intf);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
@ -1096,12 +1261,17 @@ void ipmi_lan_close(struct ipmi_intf * intf)
|
|||||||
{
|
{
|
||||||
if (!intf->abort)
|
if (!intf->abort)
|
||||||
impi_close_session_cmd(intf);
|
impi_close_session_cmd(intf);
|
||||||
|
|
||||||
if (intf->fd >= 0)
|
if (intf->fd >= 0)
|
||||||
close(intf->fd);
|
close(intf->fd);
|
||||||
|
|
||||||
ipmi_req_clear_entries();
|
ipmi_req_clear_entries();
|
||||||
|
|
||||||
if (intf->session)
|
if (intf->session)
|
||||||
free(intf->session);
|
free(intf->session);
|
||||||
|
|
||||||
intf->session = NULL;
|
intf->session = NULL;
|
||||||
|
intf->opened = 0;
|
||||||
intf = NULL;
|
intf = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1109,7 +1279,6 @@ 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;
|
struct ipmi_session *s;
|
||||||
|
|
||||||
if (!intf || !intf->session)
|
if (!intf || !intf->session)
|
||||||
@ -1129,24 +1298,24 @@ int ipmi_lan_open(struct ipmi_intf * intf)
|
|||||||
intf->abort = 1;
|
intf->abort = 1;
|
||||||
|
|
||||||
/* open port to BMC */
|
/* open port to BMC */
|
||||||
memset(&addr, 0, sizeof(struct sockaddr_in));
|
memset(&s->addr, 0, sizeof(struct sockaddr_in));
|
||||||
addr.sin_family = AF_INET;
|
s->addr.sin_family = AF_INET;
|
||||||
addr.sin_port = htons(s->port);
|
s->addr.sin_port = htons(s->port);
|
||||||
|
|
||||||
rc = inet_pton(AF_INET, s->hostname, &addr.sin_addr);
|
rc = inet_pton(AF_INET, s->hostname, &s->addr.sin_addr);
|
||||||
if (rc <= 0) {
|
if (rc <= 0) {
|
||||||
struct hostent *host = gethostbyname(s->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;
|
||||||
}
|
}
|
||||||
addr.sin_family = host->h_addrtype;
|
s->addr.sin_family = host->h_addrtype;
|
||||||
memcpy(&addr.sin_addr, host->h_addr, host->h_length);
|
memcpy(&s->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",
|
||||||
s->hostname, ntohs(addr.sin_port));
|
s->hostname, ntohs(s->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) {
|
||||||
@ -1155,7 +1324,7 @@ int ipmi_lan_open(struct ipmi_intf * intf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* connect to UDP socket so we get async errors */
|
/* connect to UDP socket so we get async errors */
|
||||||
rc = connect(intf->fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));
|
rc = connect(intf->fd, (struct sockaddr *)&s->addr, sizeof(struct sockaddr_in));
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
perror("connect failed");
|
perror("connect failed");
|
||||||
intf->close(intf);
|
intf->close(intf);
|
||||||
@ -1171,22 +1340,22 @@ int ipmi_lan_open(struct ipmi_intf * intf)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
intf->opened = 1;
|
||||||
|
|
||||||
/* try to open session */
|
/* try to open session */
|
||||||
rc = ipmi_lan_activate_session(intf);
|
rc = ipmi_lan_activate_session(intf);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
intf->close(intf);
|
intf->close(intf);
|
||||||
|
intf->opened = 0;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return intf->fd;
|
return intf->fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lan_intf_setup(struct ipmi_intf ** intf)
|
static int ipmi_lan_setup(struct ipmi_intf * intf)
|
||||||
{
|
{
|
||||||
*intf = &ipmi_lan_intf;
|
intf->session = malloc(sizeof(struct ipmi_session));
|
||||||
(*intf)->session = malloc(sizeof(struct ipmi_session));
|
memset(intf->session, 0, sizeof(struct ipmi_session));
|
||||||
memset((*intf)->session, 0, sizeof(struct ipmi_session));
|
return (intf->session) ? 0 : -1;
|
||||||
return ((*intf)->session) ? 0 : -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int intf_setup(struct ipmi_intf ** intf) __attribute__ ((weak, alias("lan_intf_setup")));
|
|
||||||
|
@ -63,12 +63,12 @@
|
|||||||
|
|
||||||
|
|
||||||
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_send_rsp(struct ipmi_intf * intf, struct ipmi_rs * rsp);
|
||||||
int ipmi_lan_open(struct ipmi_intf * intf);
|
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);
|
||||||
|
|
||||||
int lan_intf_setup(struct ipmi_intf ** intf);
|
extern struct ipmi_intf ipmi_lan_intf;
|
||||||
struct ipmi_intf ipmi_lan_intf;
|
|
||||||
|
|
||||||
#endif /*IPMI_LAN_H*/
|
#endif /*IPMI_LAN_H*/
|
||||||
|
Reference in New Issue
Block a user