mirror of
https://github.com/ipmitool/ipmitool.git
synced 2025-05-10 18:47:22 +00:00
lanplus: Make byteswapping generic
Get rid of lanplus-specific yet very generic in nature lanplus_swap() function that unconditionally swaps bytes in an arbitrary byte array. Move it to helper module and add two conditionally working interfaces to it: - array_ntoh() for network (BE) to host conversion, and - array_letoh() for ipmi (LE) to host conversion. The added functions will only perform byte swapping if the target architecture differs in endianness from the data source. array_ntoh() will only do swap on LE machines, while array_letoh() will only do it on BE ones. These functions are introduced for future use in other places of ipmitool. Partially resolves ipmitool/ipmitool#26 Signed-off-by: Alexander Amelkin <alexander@amelkin.msk.ru>
This commit is contained in:
parent
5491b12596
commit
7747d86cc4
@ -165,6 +165,9 @@ static inline void htoipmi32(uint32_t h, uint8_t *ipmi)
|
|||||||
ipmi[3] = (h >> 24) & 0xFF; /* MSB */
|
ipmi[3] = (h >> 24) & 0xFF; /* MSB */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t *array_ntoh(uint8_t *buffer, size_t length);
|
||||||
|
uint8_t *array_letoh(uint8_t *buffer, size_t length);
|
||||||
|
|
||||||
#define ipmi_open_file_read(file) ipmi_open_file(file, 0)
|
#define ipmi_open_file_read(file) ipmi_open_file(file, 0)
|
||||||
#define ipmi_open_file_write(file) ipmi_open_file(file, 1)
|
#define ipmi_open_file_write(file) ipmi_open_file(file, 1)
|
||||||
|
|
||||||
|
42
lib/helper.c
42
lib/helper.c
@ -228,6 +228,48 @@ void printbuf(const uint8_t * buf, int len, const char * desc)
|
|||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unconditionally reverse the order of arbitrarily long strings of bytes
|
||||||
|
*/
|
||||||
|
static uint8_t *_ipmi_byteswap(uint8_t *buffer, size_t length)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
uint8_t temp;
|
||||||
|
size_t max = length - 1;
|
||||||
|
|
||||||
|
for (i = 0; i < length / 2; ++i) {
|
||||||
|
temp = buffer[i];
|
||||||
|
buffer[i] = buffer[max - i];
|
||||||
|
buffer[max - i] = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Convert data array from network (big-endian) to host byte order */
|
||||||
|
uint8_t *array_ntoh(uint8_t *buffer, size_t length)
|
||||||
|
{
|
||||||
|
#if WORDS_BIGENDIAN
|
||||||
|
/* Big-endian host doesn't need conversion from big-endian network */
|
||||||
|
return buffer;
|
||||||
|
#else
|
||||||
|
/* Little-endian host needs conversion from big-endian network */
|
||||||
|
return _ipmi_byteswap(buffer, length);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Convert data array from little-endian to host byte order */
|
||||||
|
uint8_t *array_letoh(uint8_t *buffer, size_t length)
|
||||||
|
{
|
||||||
|
#if WORDS_BIGENDIAN
|
||||||
|
/* Big-endian host needs conversion from little-endian IPMI */
|
||||||
|
return _ipmi_byteswap(buffer, length);
|
||||||
|
#else
|
||||||
|
/* Little-endian host doesn't need conversion from little-endian IPMI */
|
||||||
|
return buffer;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/* str2mac - parse-out MAC address from given string and store it
|
/* str2mac - parse-out MAC address from given string and store it
|
||||||
* into buffer.
|
* into buffer.
|
||||||
*
|
*
|
||||||
|
@ -276,28 +276,6 @@ int lanplus_get_requested_ciphers(int cipher_suite_id,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Reverse the order of arbitrarily long strings of bytes
|
|
||||||
*/
|
|
||||||
void lanplus_swap(
|
|
||||||
uint8_t * buffer,
|
|
||||||
int length)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
uint8_t temp;
|
|
||||||
|
|
||||||
for (i =0; i < length/2; ++i)
|
|
||||||
{
|
|
||||||
temp = buffer[i];
|
|
||||||
buffer[i] = buffer[length - 1 - i];
|
|
||||||
buffer[length - 1 - i] = temp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static const struct valstr plus_payload_types_vals[] = {
|
static const struct valstr plus_payload_types_vals[] = {
|
||||||
{ IPMI_PAYLOAD_TYPE_IPMI, "IPMI (0)" }, // IPMI Message
|
{ IPMI_PAYLOAD_TYPE_IPMI, "IPMI (0)" }, // IPMI Message
|
||||||
{ IPMI_PAYLOAD_TYPE_SOL, "SOL (1)" }, // SOL (Serial over LAN)
|
{ IPMI_PAYLOAD_TYPE_SOL, "SOL (1)" }, // SOL (Serial over LAN)
|
||||||
@ -1010,31 +988,19 @@ read_rakp2_message(
|
|||||||
/* RAKP response code */
|
/* RAKP response code */
|
||||||
rsp->payload.rakp2_message.rakp_return_code = rsp->data[offset + 1];
|
rsp->payload.rakp2_message.rakp_return_code = rsp->data[offset + 1];
|
||||||
|
|
||||||
/* Console session ID */
|
/* Console session ID */
|
||||||
memcpy(&(rsp->payload.rakp2_message.console_id),
|
rsp->payload.rakp2_message.console_id = ipmi32toh(&rsp->data[offset + 4]);
|
||||||
rsp->data + offset + 4,
|
|
||||||
4);
|
|
||||||
#if WORDS_BIGENDIAN
|
|
||||||
rsp->payload.rakp2_message.console_id =
|
|
||||||
BSWAP_32(rsp->payload.rakp2_message.console_id);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* BMC random number */
|
/* BMC random number */
|
||||||
memcpy(&(rsp->payload.rakp2_message.bmc_rand),
|
memcpy(&(rsp->payload.rakp2_message.bmc_rand),
|
||||||
rsp->data + offset + 8,
|
array_letoh(&rsp->data[offset + 8], 16),
|
||||||
16);
|
16);
|
||||||
#if WORDS_BIGENDIAN
|
|
||||||
lanplus_swap(rsp->payload.rakp2_message.bmc_rand, 16);
|
/* BMC GUID */
|
||||||
#endif
|
memcpy(&(rsp->payload.rakp2_message.bmc_guid),
|
||||||
|
array_letoh(&rsp->data[offset + 24], 16),
|
||||||
|
16);
|
||||||
|
|
||||||
/* BMC GUID */
|
|
||||||
memcpy(&(rsp->payload.rakp2_message.bmc_guid),
|
|
||||||
rsp->data + offset + 24,
|
|
||||||
16);
|
|
||||||
#if WORDS_BIGENDIAN
|
|
||||||
lanplus_swap(rsp->payload.rakp2_message.bmc_guid, 16);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Key exchange authentication code */
|
/* Key exchange authentication code */
|
||||||
switch (auth_alg)
|
switch (auth_alg)
|
||||||
{
|
{
|
||||||
@ -1110,16 +1076,9 @@ read_rakp4_message(
|
|||||||
/* RAKP response code */
|
/* RAKP response code */
|
||||||
rsp->payload.rakp4_message.rakp_return_code = rsp->data[offset + 1];
|
rsp->payload.rakp4_message.rakp_return_code = rsp->data[offset + 1];
|
||||||
|
|
||||||
/* Console session ID */
|
/* Console session ID */
|
||||||
memcpy(&(rsp->payload.rakp4_message.console_id),
|
rsp->payload.rakp4_message.console_id = ipmi32toh(&rsp->data[offset + 4]);
|
||||||
rsp->data + offset + 4,
|
|
||||||
4);
|
|
||||||
#if WORDS_BIGENDIAN
|
|
||||||
rsp->payload.rakp4_message.console_id =
|
|
||||||
BSWAP_32(rsp->payload.rakp4_message.console_id);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* Integrity check value */
|
/* Integrity check value */
|
||||||
switch (auth_alg)
|
switch (auth_alg)
|
||||||
{
|
{
|
||||||
@ -1230,25 +1189,15 @@ read_session_data_v2x(
|
|||||||
rsp->session.payloadtype = rsp->data[(*offset)++] & 0x3F;
|
rsp->session.payloadtype = rsp->data[(*offset)++] & 0x3F;
|
||||||
|
|
||||||
/* Session ID */
|
/* Session ID */
|
||||||
memcpy(&rsp->session.id, rsp->data + *offset, 4);
|
rsp->session.id = ipmi32toh(&rsp->data[*offset]);
|
||||||
*offset += 4;
|
*offset += 4;
|
||||||
#if WORDS_BIGENDIAN
|
|
||||||
rsp->session.id = BSWAP_32(rsp->session.id);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* Ignored, so far */
|
/* Ignored, so far */
|
||||||
memcpy(&rsp->session.seq, rsp->data + *offset, 4);
|
rsp->session.seq = ipmi32toh(&rsp->data[*offset]);
|
||||||
*offset += 4;
|
*offset += 4;
|
||||||
#if WORDS_BIGENDIAN
|
|
||||||
rsp->session.seq = BSWAP_32(rsp->session.seq);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
memcpy(&rsp->session.msglen, rsp->data + *offset, 2);
|
rsp->session.msglen = ipmi16toh(&rsp->data[*offset]);
|
||||||
*offset += 2;
|
*offset += 2;
|
||||||
#if WORDS_BIGENDIAN
|
|
||||||
rsp->session.msglen = BSWAP_16(rsp->session.msglen);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2807,7 +2756,6 @@ ipmi_close_session_cmd(struct ipmi_intf * intf)
|
|||||||
struct ipmi_rs * rsp;
|
struct ipmi_rs * rsp;
|
||||||
struct ipmi_rq req;
|
struct ipmi_rq req;
|
||||||
uint8_t msg_data[4];
|
uint8_t msg_data[4];
|
||||||
uint32_t bmc_session_lsbf;
|
|
||||||
uint8_t backupBridgePossible;
|
uint8_t backupBridgePossible;
|
||||||
|
|
||||||
if (intf->session == NULL
|
if (intf->session == NULL
|
||||||
@ -2819,12 +2767,7 @@ ipmi_close_session_cmd(struct ipmi_intf * intf)
|
|||||||
intf->target_addr = IPMI_BMC_SLAVE_ADDR;
|
intf->target_addr = IPMI_BMC_SLAVE_ADDR;
|
||||||
bridgePossible = 0;
|
bridgePossible = 0;
|
||||||
|
|
||||||
bmc_session_lsbf = intf->session->v2_data.bmc_id;
|
htoipmi32(intf->session->v2_data.bmc_id, msg_data);
|
||||||
#if WORDS_BIGENDIAN
|
|
||||||
bmc_session_lsbf = BSWAP_32(bmc_session_lsbf);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
memcpy(&msg_data, &bmc_session_lsbf, 4);
|
|
||||||
|
|
||||||
memset(&req, 0, sizeof(req));
|
memset(&req, 0, sizeof(req));
|
||||||
req.msg.netfn = IPMI_NETFN_APP;
|
req.msg.netfn = IPMI_NETFN_APP;
|
||||||
@ -3101,9 +3044,7 @@ ipmi_lanplus_rakp1(struct ipmi_intf * intf)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
memcpy(msg + 8, session->v2_data.console_rand, 16);
|
memcpy(msg + 8, session->v2_data.console_rand, 16);
|
||||||
#if WORDS_BIGENDIAN
|
array_letoh(msg + 8, 16);
|
||||||
lanplus_swap(msg + 8, 16);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (verbose > 1)
|
if (verbose > 1)
|
||||||
printbuf(session->v2_data.console_rand, 16,
|
printbuf(session->v2_data.console_rand, 16,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user