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) #define BUF2STR_MAXIMUM_OUTPUT_SIZE (3*1024 + 1)
const char * buf2str_extended(const uint8_t *buf, int len, const char *sep); const char * buf2str_extended(const uint8_t *buf, int len, const char *sep);
const char * buf2str(const uint8_t *buf, int len); 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); void printbuf(const uint8_t * buf, int len, const char * desc);
uint8_t ipmi_csum(uint8_t * d, int s); uint8_t ipmi_csum(uint8_t * d, int s);
FILE * ipmi_open_file(const char * file, int rw); FILE * ipmi_open_file(const char * file, int rw);

View File

@ -51,6 +51,7 @@
#include <fcntl.h> #include <fcntl.h>
#include <errno.h> #include <errno.h>
#include <assert.h> #include <assert.h>
#include <ctype.h>
#if HAVE_CONFIG_H #if HAVE_CONFIG_H
# include <config.h> # include <config.h>
@ -140,6 +141,80 @@ buf2str(const uint8_t *buf, int len)
return buf2str_extended(buf, len, NULL); 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) void printbuf(const uint8_t * buf, int len, const char * desc)
{ {
int i; int i;

View File

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