From 4c3d43ed2482df213a77abd68b17af149baf9a55 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 20 Apr 2018 16:28:12 +0200 Subject: parse-util: add explicit parsers for MTU values We use MTUs all over the place, let's add a unified, strict parser for it, that takes MTU ranges into account. We already have parse_ifindex() close-by, hence this appears to be a natural addition, in particular as the range checking is not entirely trivial to do, as it depends on the protocol used. --- src/basic/parse-util.c | 26 ++++++++++++++++++++++++++ src/basic/parse-util.h | 1 + src/test/test-parse-util.c | 23 +++++++++++++++++++++++ 3 files changed, 50 insertions(+) diff --git a/src/basic/parse-util.c b/src/basic/parse-util.c index 5999c8140..ffad4ef45 100644 --- a/src/basic/parse-util.c +++ b/src/basic/parse-util.c @@ -11,12 +11,14 @@ #include #include #include +//#include #include "alloc-util.h" #include "errno-list.h" //#include "extract-word.h" #include "locale-util.h" #include "macro.h" +//#include "missing.h" #include "parse-util.h" #include "process-util.h" #include "string-util.h" @@ -96,6 +98,30 @@ int parse_ifindex(const char *s, int *ret) { return 0; } +int parse_mtu(int family, const char *s, uint32_t *ret) { + uint64_t u; + size_t m; + int r; + + r = parse_size(s, 1024, &u); + if (r < 0) + return r; + + if (u > UINT32_MAX) + return -ERANGE; + + if (family == AF_INET6) + m = IPV6_MIN_MTU; /* This is 1280 */ + else + m = IPV4_MIN_MTU; /* For all other protocols, including 'unspecified' we assume the IPv4 minimal MTU */ + + if (u < m) + return -ERANGE; + + *ret = (uint32_t) u; + return 0; +} + int parse_size(const char *t, uint64_t base, uint64_t *size) { /* Soo, sometimes we want to parse IEC binary suffixes, and diff --git a/src/basic/parse-util.h b/src/basic/parse-util.h index dfc50f50b..9250b6fe0 100644 --- a/src/basic/parse-util.h +++ b/src/basic/parse-util.h @@ -22,6 +22,7 @@ int parse_dev(const char *s, dev_t *ret); int parse_pid(const char *s, pid_t* ret_pid); int parse_mode(const char *s, mode_t *ret); int parse_ifindex(const char *s, int *ret); +int parse_mtu(int family, const char *s, uint32_t *ret); int parse_size(const char *t, uint64_t base, uint64_t *size); #if 0 /// UNNEEDED by elogind diff --git a/src/test/test-parse-util.c b/src/test/test-parse-util.c index e8c12710a..8f3cf671f 100644 --- a/src/test/test-parse-util.c +++ b/src/test/test-parse-util.c @@ -9,6 +9,7 @@ #include #include #include +//#include #include "alloc-util.h" #include "errno-list.h" @@ -764,6 +765,27 @@ static void test_parse_syscall_and_errno(void) { assert_se(parse_syscall_and_errno("hoge:", &n, &e) == -EINVAL); } +static void test_parse_mtu(void) { + uint32_t mtu = 0; + + assert_se(parse_mtu(AF_UNSPEC, "1500", &mtu) >= 0 && mtu == 1500); + assert_se(parse_mtu(AF_UNSPEC, "1400", &mtu) >= 0 && mtu == 1400); + assert_se(parse_mtu(AF_UNSPEC, "65535", &mtu) >= 0 && mtu == 65535); + assert_se(parse_mtu(AF_UNSPEC, "65536", &mtu) >= 0 && mtu == 65536); + assert_se(parse_mtu(AF_UNSPEC, "4294967295", &mtu) >= 0 && mtu == 4294967295); + assert_se(parse_mtu(AF_UNSPEC, "500", &mtu) >= 0 && mtu == 500); + assert_se(parse_mtu(AF_UNSPEC, "1280", &mtu) >= 0 && mtu == 1280); + assert_se(parse_mtu(AF_INET6, "1280", &mtu) >= 0 && mtu == 1280); + assert_se(parse_mtu(AF_INET6, "1279", &mtu) == -ERANGE); + assert_se(parse_mtu(AF_UNSPEC, "4294967296", &mtu) == -ERANGE); + assert_se(parse_mtu(AF_INET6, "4294967296", &mtu) == -ERANGE); + assert_se(parse_mtu(AF_INET6, "68", &mtu) == -ERANGE); + assert_se(parse_mtu(AF_UNSPEC, "68", &mtu) >= 0 && mtu == 68); + assert_se(parse_mtu(AF_UNSPEC, "67", &mtu) == -ERANGE); + assert_se(parse_mtu(AF_UNSPEC, "0", &mtu) == -ERANGE); + assert_se(parse_mtu(AF_UNSPEC, "", &mtu) == -EINVAL); +} + int main(int argc, char *argv[]) { log_parse_environment(); log_open(); @@ -790,6 +812,7 @@ int main(int argc, char *argv[]) { test_parse_dev(); test_parse_errno(); test_parse_syscall_and_errno(); + test_parse_mtu(); return 0; } -- cgit v1.2.3