Moved ipmi_parse_hex() to helper.c

This commit is contained in:
Dmitry Rakhchev 2016-06-30 21:25:25 +03:00 committed by Zdenek Styblik
parent ea46724878
commit f9211f8ed9
3 changed files with 102 additions and 53 deletions

View File

@ -100,6 +100,7 @@ uint32_t buf2long(uint8_t * buf);
#define BUF2STR_MAXIMUM_OUTPUT_SIZE (3*1024 + 1)
const char * buf2str_extended(const uint8_t *buf, int len, const char *sep);
const char * buf2str(const uint8_t *buf, int len);
int ipmi_parse_hex(const char *str, uint8_t *out, int size);
void printbuf(const uint8_t * buf, int len, const char * desc);
uint8_t ipmi_csum(uint8_t * d, int s);
FILE * ipmi_open_file(const char * file, int rw);

View File

@ -51,6 +51,7 @@
#include <fcntl.h>
#include <errno.h>
#include <assert.h>
#include <ctype.h>
#if HAVE_CONFIG_H
# include <config.h>
@ -140,6 +141,80 @@ buf2str(const uint8_t *buf, int len)
return buf2str_extended(buf, len, NULL);
}
/* ipmi_parse_hex - convert hexadecimal numbers to ascii string
* Input string must be composed of two-characer
* hexadecimal numbers.
* There is no separator between the numbers. Each number
* results in one byte of the converted string.
*
* Example: ipmi_parse_hex("50415353574F5244")
* returns 'PASSWORD'
*
* @param str: input string. It must contain only even number
* of '0'-'9','a'-'f' and 'A-F' characters.
* @param out: pointer to output data
* @param size: size of the output buffer
* @returns 0 for empty input string
* -1 for string with odd length
* -2 if out is NULL
* -3 if there is non-hexadecimal char in string
* >0 length of resulting binary data even if it is > size
*/
int
ipmi_parse_hex(const char *str, uint8_t *out, int size)
{
const char *p;
uint8_t *q;
uint8_t d = 0;
uint8_t b = 0;
int shift = 4;
int len;
len = strlen(str);
if (len == 0) {
return 0;
}
if (len % 2 != 0) {
return -1;
}
len /= 2; /* out bytes */
if (out == NULL) {
return -2;
}
for (p = str, q = out; *p; p++) {
if (!isxdigit(*p)) {
return -3;
}
if (*p < 'A') {
/* it must be 0-9 */
d = *p - '0';
} else {
/* it's A-F or a-f */
/* convert to lowercase and to 10-15 */
d = (*p | 0x20) - 'a' + 10;
}
if (q < (out + size)) {
/* there is space, store */
b += d << shift;
if (shift) {
shift = 0;
} else {
shift = 4;
*q = b;
b = 0;
q++;
}
}
}
return len;
}
void printbuf(const uint8_t * buf, int len, const char * desc)
{
int i;

View File

@ -291,67 +291,40 @@ void ipmi_catch_sigint()
exit(-1);
}
/* ipmi_parse_hex - convert hexadecimal numbers to ascii string
* Input string must be composed of two-characer hexadecimal numbers.
* There is no separator between the numbers. Each number results in one character
* of the converted string.
/* ipmi_parse_hex_KG - get hexadecimal key value
* Input string must be composed of two-characer
* hexadecimal numbers.
* There is no separator between the numbers. Each number
* results in one byte of the converted string.
*
* Example: ipmi_parse_hex("50415353574F5244") returns 'PASSWORD'
* Example: ipmi_parse_hex("50415353574F5244")
* returns 'PASSWORD'
*
* @param str: input string. It must contain only even number of '0'-'9','a'-'f' and 'A-F' characters.
* @returns converted ascii string
* @returns NULL on error
* @param str: input string. It must contain only even number
* of '0'-'9','a'-'f' and 'A-F' characters.
* @returns obtained key or NULL on error
*/
static unsigned char *
ipmi_parse_hex(const char *str)
static uint8_t *
ipmi_parse_hex_KG(const char *str)
{
const char * p;
unsigned char * out, *q;
unsigned char b = 0;
int shift = 4;
int rc;
uint8_t *out;
if (strlen(str) == 0)
return NULL;
out = calloc(IPMI_KG_BUFFER_SIZE, sizeof(uint8_t));
rc = ipmi_parse_hex(str, out, IPMI_KG_BUFFER_SIZE - 1);
if (strlen(str) % 2 != 0) {
if (rc == -1) {
lprintf(LOG_ERR, "Number of hex_kg characters is not even");
return NULL;
}
if (strlen(str) > (IPMI_KG_BUFFER_SIZE-1)*2) {
lprintf(LOG_ERR, "Kg key is too long");
return NULL;
}
out = calloc(IPMI_KG_BUFFER_SIZE, sizeof(unsigned char));
if (out == NULL) {
} else if (rc == -2) {
lprintf(LOG_ERR, "malloc failure");
return NULL;
} else if (rc == -3) {
lprintf(LOG_ERR, "Kg_hex is not hexadecimal number");
} else if (rc > (IPMI_KG_BUFFER_SIZE-1)) {
lprintf(LOG_ERR, "Kg key is too long");
free(out);
out = NULL;
}
for (p = str, q = out; *p; p++) {
if (!isxdigit(*p)) {
lprintf(LOG_ERR, "Kg_hex is not hexadecimal number");
free(out);
out = NULL;
return NULL;
}
if (*p < 'A') /* it must be 0-9 */
b = *p - '0';
else /* it's A-F or a-f */
b = (*p | 0x20) - 'a' + 10; /* convert to lowercase and to 10-15 */
*q = *q + (b << shift);
if (shift)
shift = 0;
else {
shift = 4;
q++;
}
}
return out;
return (unsigned char *)out;
}
static uint8_t
@ -577,7 +550,7 @@ ipmi_main(int argc, char ** argv,
free(kgkey);
kgkey = NULL;
}
kgkey = ipmi_parse_hex(optarg);
kgkey = ipmi_parse_hex_KG(optarg);
if (kgkey == NULL) {
goto out_free;
}