diff options
author | David Heidelberg <david@ixit.cz> | 2017-07-17 11:59:17 +0200 |
---|---|---|
committer | David Heidelberg <david@ixit.cz> | 2017-07-31 18:49:10 +0200 |
commit | 5832ec8dbd02aeaf1ee596697645c528df9daba1 (patch) | |
tree | 6e6a2be9e817a6d0b13d943dffe34117c104a194 | |
parent | 25290b6d897ffeb3972013ae9538fae0a5bb1957 (diff) | |
download | iputils-5832ec8dbd02aeaf1ee596697645c528df9daba1.tar.gz |
ping: flowinfo: fixup checks for flowinfo and also add decimal numbers support
Signed-off-by: David Heidelberg <david@ixit.cz>
-rw-r--r-- | ping.c | 35 | ||||
-rw-r--r-- | ping.h | 1 | ||||
-rw-r--r-- | ping6_common.c | 21 |
3 files changed, 30 insertions, 27 deletions
@@ -97,6 +97,7 @@ static void usage(void) __attribute__((noreturn)); static unsigned short in_cksum(const unsigned short *addr, int len, unsigned short salt); static void pr_icmph(__u8 type, __u8 code, __u32 info, struct icmphdr *icp); static int parsetos(char *str); +static int parseflow(char *str); static struct { struct cmsghdr cm; @@ -267,11 +268,7 @@ main(int argc, char **argv) hints.ai_family = AF_INET6; break; case 'F': - flowlabel = hextoui(optarg); - if (errno || (flowlabel & ~IPV6_FLOWINFO_FLOWLABEL)) { - fprintf(stderr, "ping: Invalid flowinfo %s\n", optarg); - exit(2); - } + flowlabel = parseflow(optarg); options |= F_FLOWINFO; break; case 'N': @@ -1629,6 +1626,34 @@ int parsetos(char *str) return(tos); } +int parseflow(char *str) +{ + const char *cp; + unsigned long val; + char *ep; + + /* handle both hex and decimal values */ + if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) { + cp = str + 2; + val = (int)strtoul(cp, &ep, 16); + } else + val = (int)strtoul(str, &ep, 10); + + /* doesn't look like decimal or hex, eh? */ + if (*ep != '\0') { + fprintf(stderr, "ping: \"%s\" bad value for flowinfo\n", str); + exit(2); + } + + if (val & ~IPV6_FLOWINFO_FLOWLABEL) { /* Flow is 20 bit value */ + fprintf(stderr, "ping: \"%s\" value is greater than 20 bits.\n", str); + exit(2); + } + return(val); +} + + + void ping4_install_filter(socket_st *sock) { static int once; @@ -342,7 +342,6 @@ void ping6_install_filter(socket_st *sockets); extern ping_func_set_st ping6_func_set; int niquery_option_handler(const char *opt_arg); -int hextoui(const char *str); extern __u32 tclass; extern __u32 flowlabel; diff --git a/ping6_common.c b/ping6_common.c index f5c81fd..45f39cc 100644 --- a/ping6_common.c +++ b/ping6_common.c @@ -610,27 +610,6 @@ int niquery_option_handler(const char *opt_arg) return ret; } -int hextoui(const char *str) -{ - unsigned long val; - char *ep; - - errno = 0; - val = strtoul(str, &ep, 16); - if (*ep) { - if (!errno) - errno = EINVAL; - return -1; - } - - if (val > UINT_MAX) { - errno = ERANGE; - return UINT_MAX; - } - - return val; -} - int ping6_run(int argc, char **argv, struct addrinfo *ai, struct socket_st *sock) { static const struct addrinfo hints = { .ai_family = AF_INET6, .ai_flags = getaddrinfo_flags }; |