From 0bef655f107929c6eda6e75d32b3415b2b78d438 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Wed, 31 Dec 2008 14:34:13 -0800 Subject: [PATCH] New functions for parsing integers. --- lib/util.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++ lib/util.h | 7 +++++++ utilities/dpctl.c | 24 +++++++++++----------- 3 files changed, 70 insertions(+), 12 deletions(-) diff --git a/lib/util.c b/lib/util.c index abf005d3..a577ff5b 100644 --- a/lib/util.c +++ b/lib/util.c @@ -242,3 +242,54 @@ ofp_hex_dump(FILE *stream, const void *buf_, size_t size, size -= n; } } + +bool +str_to_int(const char *s, int base, int *i) +{ + long long ll; + bool ok = str_to_llong(s, base, &ll); + *i = ll; + return ok; +} + +bool +str_to_long(const char *s, int base, long *li) +{ + long long ll; + bool ok = str_to_llong(s, base, &ll); + *li = ll; + return ok; +} + +bool +str_to_llong(const char *s, int base, long long *x) +{ + int save_errno = errno; + char *tail; + errno = 0; + *x = strtoll(s, &tail, base); + if (errno == EINVAL || errno == ERANGE || tail == s || *tail != '\0') { + errno = save_errno; + *x = 0; + return false; + } else { + errno = save_errno; + return true; + } +} + +bool +str_to_uint(const char *s, int base, unsigned int *u) +{ + return str_to_int(s, base, (int *) u); +} + +bool str_to_ulong(const char *s, int base, unsigned long *ul) +{ + return str_to_long(s, base, (long *) ul); +} + +bool str_to_ullong(const char *s, int base, unsigned long long *ull) +{ + return str_to_llong(s, base, (long long *) ull); +} diff --git a/lib/util.h b/lib/util.h index 2086a2ba..10803d1b 100644 --- a/lib/util.h +++ b/lib/util.h @@ -114,6 +114,13 @@ void ofp_fatal(int err_no, const char *format, ...) void ofp_error(int err_no, const char *format, ...) PRINTF_FORMAT(2, 3); void ofp_hex_dump(FILE *, const void *, size_t, uintptr_t offset, bool ascii); +bool str_to_int(const char *, int base, int *); +bool str_to_long(const char *, int base, long *); +bool str_to_llong(const char *, int base, long long *); +bool str_to_uint(const char *, int base, unsigned int *); +bool str_to_ulong(const char *, int base, unsigned long *); +bool str_to_ullong(const char *, int base, unsigned long long *); + #ifdef __cplusplus } #endif diff --git a/utilities/dpctl.c b/utilities/dpctl.c index 4b03bf26..1bc2647b 100644 --- a/utilities/dpctl.c +++ b/utilities/dpctl.c @@ -516,7 +516,7 @@ do_dump_tables(const struct settings *s, int argc, char *argv[]) static uint32_t -str_to_int(const char *str) +str_to_u32(const char *str) { char *tail; uint32_t value; @@ -628,7 +628,7 @@ str_to_action(char *str, struct ofp_action_header *actions, act_len = sizeof *va; va->type = htons(OFPAT_SET_VLAN_VID); - va->vlan_vid = htons(str_to_int(arg)); + va->vlan_vid = htons(str_to_u32(arg)); } else if (!strcasecmp(act, "mod_vlan_pcp")) { struct ofp_action_vlan_pcp *va = (struct ofp_action_vlan_pcp *)ah; @@ -638,11 +638,11 @@ str_to_action(char *str, struct ofp_action_header *actions, act_len = sizeof *va; va->type = htons(OFPAT_SET_VLAN_PCP); - va->vlan_pcp = str_to_int(arg); + va->vlan_pcp = str_to_u32(arg); } else if (!strcasecmp(act, "strip_vlan")) { ah->type = htons(OFPAT_STRIP_VLAN); } else if (!strcasecmp(act, "output")) { - port = str_to_int(arg); + port = str_to_u32(arg); #ifdef SUPPORT_SNAT } else if (!strcasecmp(act, "nat")) { struct nx_action_snat *sa = (struct nx_action_snat *)ah; @@ -651,7 +651,7 @@ str_to_action(char *str, struct ofp_action_header *actions, ofp_fatal(0, "Insufficient room for SNAT action\n"); } - if (str_to_int(arg) > OFPP_MAX) { + if (str_to_u32(arg) > OFPP_MAX) { ofp_fatal(0, "Invalid nat port: %s\n", arg); } @@ -659,7 +659,7 @@ str_to_action(char *str, struct ofp_action_header *actions, sa->type = htons(OFPAT_VENDOR); sa->vendor = htonl(NX_VENDOR_ID); sa->subtype = htons(NXAST_SNAT); - sa->port = htons(str_to_int(arg)); + sa->port = htons(str_to_u32(arg)); #endif } else if (!strcasecmp(act, "TABLE")) { port = OFPP_TABLE; @@ -683,12 +683,12 @@ str_to_action(char *str, struct ofp_action_header *actions, /* Unless a numeric argument is specified, we send the whole * packet to the controller. */ if (arg && (strspn(act, "0123456789") == strlen(act))) { - ca->max_len= htons(str_to_int(arg)); + ca->max_len= htons(str_to_u32(arg)); } } else if (!strcasecmp(act, "LOCAL")) { port = OFPP_LOCAL; } else if (strspn(act, "0123456789") == strlen(act)) { - port = str_to_int(act); + port = str_to_u32(act); } else { ofp_fatal(0, "Unknown action: %s", act); } @@ -860,9 +860,9 @@ str_to_flow(char *string, struct ofp_match *match, } else { wildcards &= ~f->wildcard; if (f->type == F_U8) { - *(uint8_t *) data = str_to_int(value); + *(uint8_t *) data = str_to_u32(value); } else if (f->type == F_U16) { - *(uint16_t *) data = htons(str_to_int(value)); + *(uint16_t *) data = htons(str_to_u32(value)); } else if (f->type == F_MAC) { str_to_mac(value, data); } else if (f->type == F_IP) { @@ -927,7 +927,7 @@ static void do_add_snat(const struct settings *s, int argc, char *argv[]) nac->type = htons(NXAST_SNAT); nac->snat[0].command = NXSC_ADD; - nac->snat[0].port = htons(str_to_int(argv[2])); + nac->snat[0].port = htons(str_to_u32(argv[2])); nac->snat[0].mac_timeout = htons(0); str_to_ip(argv[3], &nac->snat[0].ip_addr_start); str_to_ip(argv[3], &nac->snat[0].ip_addr_end); @@ -953,7 +953,7 @@ static void do_del_snat(const struct settings *s, int argc, char *argv[]) nac->type = htons(NXAST_SNAT); nac->snat[0].command = NXSC_DELETE; - nac->snat[0].port = htons(str_to_int(argv[2])); + nac->snat[0].port = htons(str_to_u32(argv[2])); nac->snat[0].mac_timeout = htons(0); open_vconn(argv[1], &vconn); -- 2.30.2