diff --git a/ipmitool/include/ipmitool/helper.h b/ipmitool/include/ipmitool/helper.h index 984b1f9..f7160d6 100644 --- a/ipmitool/include/ipmitool/helper.h +++ b/ipmitool/include/ipmitool/helper.h @@ -76,6 +76,7 @@ int str2char(const char * str, int8_t * chr_ptr); int str2uchar(const char * str, uint8_t * uchr_ptr); int is_fru_id(const char *argv_ptr, uint8_t *fru_id_ptr); +int is_ipmi_channel_num(const char *argv_ptr, uint8_t *channel_ptr); uint16_t str2val(const char * str, const struct valstr * vs); void print_valstr(const struct valstr * vs, const char * title, int loglevel); diff --git a/ipmitool/lib/helper.c b/ipmitool/lib/helper.c index 6d7e442..230862a 100644 --- a/ipmitool/lib/helper.c +++ b/ipmitool/lib/helper.c @@ -693,3 +693,34 @@ is_fru_id(const char *argv_ptr, uint8_t *fru_id_ptr) argv_ptr); return (-1); } /* is_fru_id(...) */ + +/* is_ipmi_channel_num - wrapper for str-2-int Channel conversion. Message is + * printed on error. + * + * 6.3 Channel Numbers, p. 45, IPMIv2 spec. + * Valid channel numbers are: <0..7>, + * Reserved channel numbers: <8-D> + * + * @argv_ptr: source string to convert from; usually argv + * @channel_ptr: pointer where to store result + * + * returns zero on success + * returns (-1) on error and message is printed on STDERR + */ +int +is_ipmi_channel_num(const char *argv_ptr, uint8_t *channel_ptr) +{ + if (!argv_ptr || !channel_ptr) { + lprintf(LOG_ERR, + "is_ipmi_channel_num(): invalid argument(s)."); + return (-1); + } + if ((str2uchar(argv_ptr, channel_ptr) == 0) + && ((*channel_ptr >= 0x0 && *channel_ptr <= 0x7) + || (*channel_ptr >= 0xE && *channel_ptr <= 0xF))) { + return 0; + } + lprintf(LOG_ERR, "Given Channel number '%s' is out of range.", argv_ptr); + lprintf(LOG_ERR, "Channel number must be from ranges: <0..7>, <0xE..0xF>"); + return (-1); +} diff --git a/ipmitool/lib/ipmi_firewall.c b/ipmitool/lib/ipmi_firewall.c index b378c24..0ddc568 100644 --- a/ipmitool/lib/ipmi_firewall.c +++ b/ipmitool/lib/ipmi_firewall.c @@ -82,36 +82,57 @@ static int ipmi_firewall_parse_args(int argc, char ** argv, struct ipmi_function_params * p) { int i; + uint8_t conv_err = 0; if (!p) { lprintf(LOG_ERR, "ipmi_firewall_parse_args: p is NULL"); return -1; } for (i=0; ichannel = strtol(argv[i], NULL, 0); + if (strncmp(argv[i], "channel", 7) == 0 && (++i < argc)) { + uint8_t channel_tmp = 0; + if (is_ipmi_channel_num(argv[i], &channel_tmp) != 0) { + conv_err = 1; + break; + } else { + p->channel = channel_tmp; + } } - else if (strncmp(argv[i], "lun", 3) == 0) { - if (++i < argc) - p->lun = strtol(argv[i], NULL, 0); + else if (strncmp(argv[i], "lun", 3) == 0 && (++i < argc)) { + if (str2int(argv[i], &(p->lun)) != 0) { + lprintf(LOG_ERR, "Given lun '%s' is invalid.", argv[i]); + conv_err = 1; + break; + } } else if (strncmp(argv[i], "force", 5) == 0) { p->force = 1; } - else if (strncmp(argv[i], "netfn", 5) == 0) { - if (++i < argc) - p->netfn = strtol(argv[i], NULL, 0); + else if (strncmp(argv[i], "netfn", 5) == 0 && (++i < argc)) { + if (str2int(argv[i], &(p->netfn)) != 0) { + lprintf(LOG_ERR, "Given netfn '%s' is invalid.", argv[i]); + conv_err = 1; + break; + } } - else if (strncmp(argv[i], "command", 7) == 0) { - if (++i < argc) - p->command = strtol(argv[i], NULL, 0); + else if (strncmp(argv[i], "command", 7) == 0 && (++i < argc)) { + if (str2int(argv[i], &(p->command)) != 0) { + lprintf(LOG_ERR, "Given command '%s' is invalid.", argv[i]); + conv_err = 1; + break; + } } - else if (strncmp(argv[i], "subfn", 5) == 0) { - if (++i < argc) - p->subfn = strtol(argv[i], NULL, 0); + else if (strncmp(argv[i], "subfn", 5) == 0 && (++i < argc)) { + if (str2int(argv[i], &(p->subfn)) != 0) { + lprintf(LOG_ERR, "Given subfn '%s' is invalid.", argv[i]); + conv_err = 1; + break; + } } } + if (conv_err != 0) { + return (-1); + } if (p->subfn >= MAX_SUBFN) { printf("subfn is out of range (0-%d)\n", MAX_SUBFN-1); return -1;