add tests
authorMazet Laurent <laurent.mazet@thalesgroup.com>
Wed, 4 Jun 2025 12:59:04 +0000 (14:59 +0200)
committerMazet Laurent <laurent.mazet@thalesgroup.com>
Wed, 4 Jun 2025 12:59:04 +0000 (14:59 +0200)
mapec.c
mapec.h
ulvpn.c
ulvpn.sh

diff --git a/mapec.c b/mapec.c
index 5f5c31aa51b202804710436fa9c2aa72f8d7dbe2..9b1ba8a735208e4ac5cd8ecdd42d33b5763d1eb0 100644 (file)
--- a/mapec.c
+++ b/mapec.c
@@ -59,6 +59,8 @@ typedef struct {
 
 #define MAX_MAPEC_NUMBER  4096
 
+#define MTU 1495
+
 /**
    List of private descriptor associated to each connected MAPEC.
 */
@@ -136,7 +138,12 @@ int parse_address (struct sockaddr_in *addr, char *url)
     }
 
     addr->sin_family = AF_INET;
-    addr->sin_port = htons (atoi (port));
+    int nport = atoi (port);
+    if (nport <= 0) {
+        errno = EINVAL;
+        return -1;
+    }
+    addr->sin_port = htons (nport);
 
     VERBOSE (mapec, INFO, PRINTF ("parse URL -> %s %s\n", hostname, port));
 
@@ -215,10 +222,25 @@ int connect_tun (MAPEC_addr_t *mapec, char *device_name, char *local_address, ch
 
     VERBOSE (mapec, TRACE, PRINTF ("connect_tun\n"));
 
+    /* parse device name */
+    int mtu = MTU;
+    int device_name_len = strlen (device_name);
+    char *pt = strchr (device_name, ':');
+    if (pt) {
+        mtu = atoi (pt + 1);
+        if (mtu <= 0) {
+            VERBOSE (mapec, ERROR, PRINTF ("can't parse MTU in '%s'\n", device_name));
+            return -1;
+        }
+        device_name_len = pt - device_name;
+    }
+
+    VERBOSE (mapec, DEBUG, PRINTF ("tun device '%.*s' %d\n", device_name_len, device_name, mtu));
+
     /* request a TUN device */
     int fid = open ("/dev/net/tun", O_RDWR);
     if (fid < 0) {
-        VERBOSE (mapec, ERROR, PRINTF ("can't open a tun device '%s'\n", device_name));
+        VERBOSE (mapec, ERROR, PRINTF ("can't open a tun device '%.*s'\n", device_name_len, device_name));
         return -1;
     }
 
@@ -228,7 +250,7 @@ int connect_tun (MAPEC_addr_t *mapec, char *device_name, char *local_address, ch
     struct ifreq ifr = { 0 };
     ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
     if (ioctl (fid, TUNSETIFF, &ifr) < 0) {
-        VERBOSE (mapec, ERROR, PRINTF ("can't link to named device '%s'\n", device_name));
+        VERBOSE (mapec, ERROR, PRINTF ("can't link to named device '%.*s'\n", device_name_len, device_name));
         return -1;
     }
 
@@ -242,24 +264,36 @@ int connect_tun (MAPEC_addr_t *mapec, char *device_name, char *local_address, ch
 
     /* get interface name */
     ifr.ifr_flags = 0;
-    strncpy(ifr.ifr_name, device_name, IFNAMSIZ);
+    strncpy(ifr.ifr_name, device_name, (IFNAMSIZ < device_name_len) ? IFNAMSIZ : device_name_len);
 
     /* set ip address */
     mapec->addrin.sin_family = AF_INET;
     mapec->addrin.sin_port   = 0;
     mapec->addrin.sin_addr.s_addr = inet_addr (local_address);
+    if (mapec->addrin.sin_addr.s_addr == INADDR_NONE) {
+        VERBOSE (mapec, ERROR, PRINTF ("can't find host '%s'\n", local_address));
+        errno = EHOSTUNREACH;
+        return -1;
+    }
     memcpy (&ifr.ifr_addr, &mapec->addrin, sizeof (struct sockaddr));
 
     if ((ioctl (sock, SIOCSIFADDR, &ifr) < 0) || (ioctl (sock, SIOCGIFFLAGS, &ifr) < 0)) {
-        VERBOSE (mapec, ERROR, PRINTF ("can't set ip address '%s' on tun device '%s'\n", local_address, device_name));
+        VERBOSE (mapec, ERROR, PRINTF ("can't set ip address '%s' on tun device '%.*s'\n", local_address, device_name_len, device_name));
         return -1;
     }
 
     ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
     if (ioctl (sock, SIOCSIFFLAGS, &ifr) < 0) {
-        VERBOSE (mapec, ERROR, PRINTF ("can't activate tun interface '%s'\n", device_name));
+        VERBOSE (mapec, ERROR, PRINTF ("can't activate tun interface '%.*s'\n", device_name_len, device_name));
         return -1;
     }
+
+    ifr.ifr_mtu = mtu;
+    if ((ioctl (sock, SIOCSIFMTU, &ifr) < 0)) {
+        VERBOSE (mapec, ERROR, PRINTF ("can't set MTU to %d on tun device '%.*s'\n", mtu, device_name_len, device_name));
+        return -1;
+    }
+
     close (sock);
 
     /* create route */
@@ -268,9 +302,19 @@ int connect_tun (MAPEC_addr_t *mapec, char *device_name, char *local_address, ch
         struct sockaddr_in *addr = (struct sockaddr_in *) &route.rt_gateway;
         addr->sin_family = AF_INET;
         addr->sin_addr.s_addr = inet_addr (local_address);
+        if (addr->sin_addr.s_addr == INADDR_NONE) {
+            VERBOSE (mapec, ERROR, PRINTF ("can't find host '%s'\n", local_address));
+            errno = EHOSTUNREACH;
+            return -1;
+        }
         addr = (struct sockaddr_in *) &route.rt_dst;
         addr->sin_family = AF_INET;
         addr->sin_addr.s_addr = inet_addr (remote_address);
+        if (addr->sin_addr.s_addr == INADDR_NONE) {
+            VERBOSE (mapec, ERROR, PRINTF ("can't find host '%s'\n", remote_address));
+            errno = EHOSTUNREACH;
+            return -1;
+        }
         addr = (struct sockaddr_in *) &route.rt_genmask;
         addr->sin_family = AF_INET;
         addr->sin_addr.s_addr = inet_addr ("255.255.255.0");
diff --git a/mapec.h b/mapec.h
index aecdd72f87bc888cb114e32dc60a39897a6483ce..9930c50e324d2aa15455b3626d1088ed172da590 100644 (file)
--- a/mapec.h
+++ b/mapec.h
@@ -43,7 +43,7 @@ __BEGIN_DECLS
    'udp://hostname:port'
    For TUN connection, first argument is the device name, second argument is
    the IP address of the tun device and third argument is the IP adresss of the
-   distant network. The syntax is tun://device, tun://ip, and tun://ip
+   distant network. The syntax is tun://device:mtu, tun://ip, and tun://ip
 
    @return a new file descriptor associated with this connection
 
diff --git a/ulvpn.c b/ulvpn.c
index 1689ea9fd9322e1e39281ad2bedaa845c1707f3d..10bb9c0c3de8843be9e96b1e9b532b8bd105bb3f 100644 (file)
--- a/ulvpn.c
+++ b/ulvpn.c
@@ -30,7 +30,7 @@
 char *progname = NULL;
 char *version = "0.1";
 
-char *devtun = "tun://tun0";
+char *devtun = "tun://tun0:1440";
 char *loctun = "tun://10.2.0.1";
 char *remtun = "tun://10.2.1.0";
 char *locudp = "udp://10.1.0.1:1234";
@@ -182,7 +182,9 @@ int main (int argc, char **argv)
         int max_fd = ((tun_fd > udp_fd) ? tun_fd : udp_fd) + 1;
 
         if (-1 == select(max_fd, &readset, NULL, NULL, NULL)) {
-            VERBOSE (ulvpn, ERROR, PRINTF ("select error\n"));
+            if (!stop) {
+                VERBOSE (ulvpn, ERROR, PRINTF ("select error\n"));
+            }
             break;
         }
 
@@ -245,6 +247,7 @@ int main (int argc, char **argv)
 }
 
 /* test: ulvpn.exe -h | grep usage */
+/* test: ulvpn.exe help 2>&1 | grep usage */
 /* test: ulvpn.exe -d 2>&1 | grep 'dev tun not specified' */
 /* test: ulvpn.exe -l 2>&1 | grep 'local tun not specified' */
 /* test: ulvpn.exe -r 2>&1 | grep 'remote tun not specified' */
@@ -252,7 +255,24 @@ int main (int argc, char **argv)
 /* test: ulvpn.exe -u 2>&1 | grep 'remote udp not specified' */
 /* test: ulvpn.exe -v 2>&1 | grep 'verbose level not specified' */
 /* test: ulvpn.exe -V 2>&1 | grep 'verbose level not specified' */
+
+/* test: ulvpn.exe -d tun://tun0:-1; test $? -ne 0 */
+/* test: ulvpn.exe -l udp://localhost:1234; test $? -ne 0 */
+/* test: ulvpn.exe -l tun://nohost.nowhere; test $? -ne 0 */
+/* test: ulvpn.exe -r udp://localhost:1234; test $? -ne 0 */
+/* test: ulvpn.exe -t tun://nohost.nowhere; test $? -ne 0 */
+/* test: ulvpn.exe -t udp://nohost.nowhere:1234; test $? -ne 0 */
+/* test: ulvpn.exe -t udp://localhost:-1; test $? -ne 0 */
+/* test: ulvpn.exe -u tun://localhost; test $? -ne 0 */
+/* test: ulvpn.exe -u udp://nohost.nowhere:1235; test $? -ne 0 */
+/* test: ulvpn.exe -u udp://localhost:-1; test $? -ne 0 */
+
 /* test: ulvpn.exe -v 5 & pid=$!; sleep 1; ip route list dev tun0; rc=$?; sleep 1; kill -TERM $pid; test $rc -eq 0 */
-/* test: ulvpn.exe -v 5 & pid=$!; sleep 1; ping -c 1 -W 1 10.2.1.1; kill -TERM $pid */
+
+/* test: ulvpn.exe -v 5 -V 5 -d tun://tun0:1496 & pid=$!; sleep 1; ping -c 1 -W 1 10.2.1.1; kill -TERM $pid */
+
+/* test: ulvpn.exe -v 5 -t udp://localhost:1234 -u udp://localhost:1235 & pid1=$!; sleep 1; nc -ul 1235 > pcap & pid2=$!; sleep 1; echo TEST | nc -Nuq0 10.2.1.1 3000; sleep 1; kill -TERM $pid1 $pid2; strings pcap | grep -q TEST */
+/* test: ulvpn.exe -v 5 -l tun://10.2.1.1 -r tun://10.2.0.0 -t udp://localhost:1234 -u udp://localhost:1235 & pid1=$!; sleep 1; nc -ul 3000 > text & pid2=$!; sleep 1; cat pcap | nc -4Nuq0 -p 1235 localhost 1234; sleep 1; kill -TERM $pid1 $pid2; test "$(cat text)" = TEST */
+/* test: rm -f pcap text */
 
 /* vim: set ts=4 sw=4 si et: */
index 91d68b3e41229e3a63a02d01f2854934503f33fb..db7e14984346cc1f02f8ed4fcd9765fea9b77bcd 100755 (executable)
--- a/ulvpn.sh
+++ b/ulvpn.sh
@@ -1,5 +1,7 @@
 #!/bin/bash
 
+MTU=1440
+[ $# -gt 0 ] && MTU=$1
 VPN=./ulvpn.exe
 
 title() { echo -e "\033[0;1m$@\033[0;0m"; }
@@ -7,13 +9,13 @@ title() { echo -e "\033[0;1m$@\033[0;0m"; }
 if $(ip add list dev enp0s4 | fgrep -q 10.1.0.2/); then
     title Remote
     $VPN -v 5 \
-      -d tun://tun0 \
+      -d tun://tun0:$MTU \
       -l tun://10.2.1.1 -r tun://10.2.0.0 \
       -u udp://10.1.0.1:1234 -t udp://10.1.0.2:1235
 else
     title Local
     $VPN -v 5 \
-      -d tun://tun0 \
+      -d tun://tun0:$MTU \
       -l tun://10.2.0.1 -r tun://10.2.1.0 \
       -t udp://10.1.0.1:1234 -u udp://10.1.0.2:1235
 fi