]> git.ipfire.org Git - network.git/commitdiff
networkd: Enumerate ports on startup
authorMichael Tremer <michael.tremer@ipfire.org>
Sat, 11 Feb 2023 10:59:03 +0000 (10:59 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Sat, 11 Feb 2023 10:59:03 +0000 (10:59 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
Makefile.am
src/networkd/port.h
src/networkd/ports.c
src/networkd/string.h
src/networkd/util.c [new file with mode: 0644]
src/networkd/util.h [new file with mode: 0644]

index d78d61ee602b10040a595485c79c29b514db72c6..505d6791d8b3f0a00e1cc8277451f7c4d3096714 100644 (file)
@@ -329,6 +329,8 @@ dist_networkd_SOURCES = \
        src/networkd/ports.c \
        src/networkd/ports.h \
        src/networkd/string.h \
+       src/networkd/util.c \
+       src/networkd/util.h \
        src/networkd/zones.c \
        src/networkd/zones.h \
        src/networkd/zone.c \
index cea6203724b7d8a160f50ce9e0f1ff19b997a8d7..250a694c547444fd746bfd26350114c88e816f9c 100644 (file)
@@ -21,6 +21,8 @@
 #ifndef NETWORKD_PORT_H
 #define NETWORKD_PORT_H
 
+#define PORT_CONFIG_DIR                        CONFIG_DIR "/ports"
+
 struct nw_port;
 
 int nw_port_create(struct nw_port** port, const char* name);
index 500153a43616bcc5de46c0b534091bc3c2fffb7e..19a3a5979c0280324d92def503b63463be4bcae9 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 #include <sys/queue.h>
+#include <sys/stat.h>
 
 #include "logging.h"
 #include "port.h"
 #include "ports.h"
+#include "string.h"
+#include "util.h"
 
 struct nw_ports_entry {
        struct nw_port* port;
@@ -95,6 +98,62 @@ struct nw_ports* nw_ports_unref(struct nw_ports* ports) {
        return NULL;
 }
 
+static int nw_ports_add_port(struct nw_ports* ports, struct nw_port* port) {
+       // Allocate a new entry
+       struct nw_ports_entry* entry = calloc(1, sizeof(*entry));
+       if (!entry)
+               return 1;
+
+       // Reference the port
+       entry->port = nw_port_ref(port);
+
+       // Add it to the list
+       STAILQ_INSERT_TAIL(&ports->entries, entry, nodes);
+
+       // Increment the counter
+       ports->num++;
+
+       return 0;
+}
+
+static int __nw_ports_enumerate(const char* path, const struct stat* s, void* data) {
+       struct nw_port* port = NULL;
+       int r;
+
+       struct nw_ports* ports = (struct nw_ports*)data;
+
+       // Skip anything that isn't a regular file
+       if (!S_ISREG(s->st_mode))
+               return 0;
+
+       // Find the basename of the file
+       const char* name = nw_path_basename(path);
+
+       // Break on invalid paths
+       if (!name)
+               return 0;
+
+       // Skip any hidden files
+       if (*name == '.')
+               return 0;
+
+       // Create a new port
+       r = nw_port_create(&port, name);
+       if (r)
+               goto ERROR;
+
+       // Add the port to the list
+       r = nw_ports_add_port(ports, port);
+       if (r)
+               goto ERROR;
+
+ERROR:
+       if (port)
+               nw_port_unref(port);
+
+       return r;
+}
+
 int nw_ports_enumerate(struct nw_ports* ports) {
-       return 0; // XXX TODO
+       return nw_ftw(PORT_CONFIG_DIR, PORT_CONFIG_DIR "/*", __nw_ports_enumerate, ports);
 }
index f3c5b7172933381f5169d0b897cf3141cabcd94a..6ff44f9ef91f838a81dedbf3de1633e25849e566 100644 (file)
@@ -142,4 +142,12 @@ static inline int __nw_path_join(char* s, const size_t length,
        return __nw_string_format(s, length, "%s/%s", first, second);
 }
 
+static inline const char* nw_path_basename(const char* path) {
+       const char* basename = strrchr(path, '/');
+       if (!basename)
+               return NULL;
+
+       return basename + 1;
+}
+
 #endif /* NETWORKD_STRING_H */
diff --git a/src/networkd/util.c b/src/networkd/util.c
new file mode 100644 (file)
index 0000000..0381ea8
--- /dev/null
@@ -0,0 +1,61 @@
+/*#############################################################################
+#                                                                             #
+# IPFire.org - A linux based firewall                                         #
+# Copyright (C) 2023 IPFire Network Development Team                          #
+#                                                                             #
+# This program is free software: you can redistribute it and/or modify        #
+# it under the terms of the GNU General Public License as published by        #
+# the Free Software Foundation, either version 3 of the License, or           #
+# (at your option) any later version.                                         #
+#                                                                             #
+# This program is distributed in the hope that it will be useful,             #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
+# GNU General Public License for more details.                                #
+#                                                                             #
+# You should have received a copy of the GNU General Public License           #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+#############################################################################*/
+
+#include <errno.h>
+#include <fnmatch.h>
+#include <ftw.h>
+#include <stddef.h>
+#include <stdio.h>
+
+#include "util.h"
+
+int nw_ftw(const char* path, const char* filter,
+               int (*callback)(const char* path, const struct stat* s, void* data), void* data) {
+       /*
+               This is a nested function which allows us to pass some custom pointer to
+               the callback function as that isn't possible with nftw().
+       */
+       int __callback(const char* p, const struct stat* s, int type, struct FTW* ftw) {
+               int r;
+
+               // Filter out anything we don't want
+               if (filter) {
+                       r = fnmatch(filter, p, FNM_PATHNAME);
+
+                       switch (r) {
+                               // Pattern didn't match
+                               case FNM_NOMATCH:
+                                       return 0;
+
+                               // Pattern matched
+                               case 0:
+                                       break;
+
+                               // Error
+                               default:
+                                       return 1;
+                       }
+               }
+
+               return callback(p, s, data);
+       }
+
+       return nftw(path, __callback, 0, 0);
+}
diff --git a/src/networkd/util.h b/src/networkd/util.h
new file mode 100644 (file)
index 0000000..950afda
--- /dev/null
@@ -0,0 +1,29 @@
+/*#############################################################################
+#                                                                             #
+# IPFire.org - A linux based firewall                                         #
+# Copyright (C) 2023 IPFire Network Development Team                          #
+#                                                                             #
+# This program is free software: you can redistribute it and/or modify        #
+# it under the terms of the GNU General Public License as published by        #
+# the Free Software Foundation, either version 3 of the License, or           #
+# (at your option) any later version.                                         #
+#                                                                             #
+# This program is distributed in the hope that it will be useful,             #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
+# GNU General Public License for more details.                                #
+#                                                                             #
+# You should have received a copy of the GNU General Public License           #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+#############################################################################*/
+
+#ifndef NETWORKD_UTIL_H
+#define NETWORKD_UTIL_H
+
+#include <sys/stat.h>
+
+int nw_ftw(const char* path, const char* filter,
+               int (*callback)(const char* path, const struct stat* s, void* data), void* data);
+
+#endif /* NETWORKD_UTIL_H */