chiark / gitweb /
parse-util: add explicit parsers for MTU values
authorLennart Poettering <lennart@poettering.net>
Fri, 20 Apr 2018 14:28:12 +0000 (16:28 +0200)
committerSven Eden <yamakuzure@gmx.net>
Fri, 24 Aug 2018 14:47:08 +0000 (16:47 +0200)
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
src/basic/parse-util.h
src/test/test-parse-util.c

index 5999c8140c4f8696e30602110504eb14dbc421ba..ffad4ef45e0e5c176e74a39fc536af125e1b4422 100644 (file)
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+//#include <sys/socket.h>
 
 #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
index dfc50f50ba95b7be5e899ca910399ddc4069a712..9250b6fe00ec7f39b6de51ee4f7cbd96745629e5 100644 (file)
@@ -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
index e8c12710a72e4838d9b52a8397b5a5a1c726b129..8f3cf671f31bf02d0381e7ab7ae18c1ba15b641d 100644 (file)
@@ -9,6 +9,7 @@
 #include <errno.h>
 #include <locale.h>
 #include <math.h>
+//#include <sys/socket.h>
 
 #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;
 }